I'm working my way through an exercise to understand Java, and basically I need to merge the functionality of two classes into one app.
I'm stuck on one area though - the referencing of objects across classes.
What I have done is set up a gui in one class (test1), and this has a textfield in ie.
chatLine = new JTextField();
in another class(test2), I was planning on leaving all the functionality in there and referencing the various gui elements set up in test1 - like this test1.chatLine
I understand this level of referencing, I tested this by setting up a test method in the test2 class
public static void testpass() {
test1.testfield.setText("hello");
}
I'm trying to understand how to implement the more complex functionality in test2 class though, specifically this existing code;
test1.chatLine.addActionListener(new ActionAdapter() {
public void actionPerformed(ActionEvent e) {
String s = Game.chatLine.getText();
if (!s.equals("")) {
appendToChatBox("OUTGOING: " + s + "\n");
Game.chatLine.selectAll();
// Send the string
sendString(s);
}
}
});
This is the bit I'm stuck on, if I should be able to do this - as it's failing on the compile, can I add the actionadapter stuff to the gui element thats sat in test1, but do this from test2 - I'm wondering if I'm trying to do something that's not possible.
Hope this makes sense, I'm pretty confused over this - I'm trying to understand how the scope and referencing works.
Ideally what i'm trying to achieve is one class that has all the main stuff in, the gui etc, then all the related functionality in the other class, and target the first class's gui elements with the results etc.
Any thoughts greatly appreciated.
If you can access chatLine in the first place, you can call its (public) methods, including addActionListener. To access chatLine directly, you need to make it public, and if you want to make it specific to the class (as opposed to a different chatLine for each instance of the class), it needs to be static.
Note, however, that it's often desirable to not make variables public. An important reason for having classes and objects in the first place is encapsulation. You might consider hiding the implementation inside the classes by making it private and only providing higher level public methods to access what is needed, e.g. do not expose the "raw" JTextField but rather expose the functionality you use it to provide.
I'm not clear on whether chatLine is a local variable, an instance variable, or a static variable. Any of these things could be the source of your compile error, which you didn't specify -- what's the error?
If it's an instance or static variable, it can be made visible from anywhere by making it public. This doesn't mean that's a good idea.
At least, it should be private and exposed via a getChatLine() method.
Even then, there's some question about whether this design is the right one, but at least you'd be doing it right at a compiler level and basic data encapsulation level.
Generally speaking everything in Java is referenced but primitive types.
The so called visibility of objects is another matter:
public scoped members are visible
to all
'Package Friendly' members (those
that have no scope explicitly
mentioned) are visible to all abjects
belonging to the same package
protected scoped members are both
'Package Friendly' and visible to all
inheriting class objects
Finally, private scoped members are
visible only to the object itself
[Objects from the same class can view
each other's private members (as far
as I can recall)]
Now,
an inner static class can access its
enclosing class's static members.
A 'normal' inner class (without the
static modifier) can access its
enclosing class's static members
and enclosing object's instance
members - that goes as well to
anonymous inner class.
Finally any chain of method/field calls as below is valid (but ugly) as long as no part of the chain 'references' a null:
myObj.getThatObject().somePublicField.doSomthing().activate().someOtherPublicField
One recommendation though is not to declare members as public...
Related
So, I'm beginning to learn Java and I think it's an awesome programming language, however I've come across the static keyword which, to my understanding, makes sure a given method or member variable is accessible through the class (e.g. MyClass.main()) rather than solely through the object (MyObject.main()). My question is, is it possible to make certain methods only accessible through the class and not through the object, so that MyClass.main() would work, however MyObject.main() would not? Whilst I'm not trying to achieve anything with this, I'd just like to know out of curiosity.
In my research I couldn't find this question being asked anywhere else, but if it is elsewhere I'd love to be pointed to it!
Forgive me if it's simple, however I've been thinking on this for a while and getting nowhere.
Thanks!
Any static method or member belongs to the class, whereas non-static members belong to the object.
Calling a static method (or using a static member) by doing myObject.method() is actually exactly the same as MyClass.method() and any proper IDE will give a suggestion to change it to the second one, since that one is actually what you are doing regardless of which of the two you use.
Now to answer the actual question:
is it possible to make certain methods only accessible through the class and not through the object
No, not as far as i know, but like I said, any proper IDE will give a warning, since it makes little sense and it gives other readers of the code an instant hint that you're dealing with static members.
Yes, short answer is no.
But you can put your static members in a dedicated class, so that no instances share any one of them.
MyObject is instance of MyClass, and you aggregate all you static parts in MyStaticThing.
Using static member on an instance can be misleading, so it is a bad practice
http://grepcode.com/file/repo1.maven.org/maven2/org.sonarsource.java/java-checks/3.4/org/sonar/l10n/java/rules/squid/S2209.html
While it is possible to access static members
from a class instance, it's bad form, and considered by most to be
misleading because it implies to the readers of your code thatthere's
an instance of the member per class instance.
Another thing, do not use static things, because you cannot do abstraction and replace implementations to extend your code.
Being able to switch between implementations is useful for maintenance and tests.
In Java, you can crete an object with these keywords.(new keyword, newInstance() method, clone() method, factory method and deserialization) And when you create an object,it can also use classes abilities which is like static methods.
Short answer:No.
Is it possible to make certain methods only accessible through the class and not through the object?
Yes, it is. You achieve this by preventing any instances of the class to ever be created, by making the class non-instantiable: declare its constructor private.
public final class NonInstantiable {
private NonInstantiable() {
throw new RuntimeException(
"This class shouldn't be instantiated -- not even through reflection!");
}
/* static methods here... */
}
Now, it only makes sense to declare any methods of the class static -- and they can only be called through the class name. Such a class is often called a utility class.
I was writing a piece of code that goes like this,
public class Grades
{
public int marks; // what's the purpose of this?
...
...
}
Objects are data and methods encapsulated together into a single software component.
Classes are templates ("cookie cutters") from which you can create one or more instances in memory ("cookies"). Each one is independent; each can have its own state.
By declaring the variable outside of any methods you've made it an attribute of the class. This means that any method in the class can access it, and depending on its encapsulation (public/private/protected/package private) other classes can access it as well.
As for that specific variable's purpose in that specific class, that cannot be determined without seeing more code.
What's the point of using access modifiers on the fields of classes which are defined inside methods ?
e.g.:
class Outer
{
public static void main (String[] args)
{
// class defined inside method
class Test
{
// applies an access modifier
public int field;
}
Test test = new Test();
}
}
Are my following 2 statements correct:
Regardless of the access modifier, still the only way to access the field from outside the scope of this method, is using reflection.
Regardless of the access modifier, the field can always be accessed inside the scope of the method, even when the field is private without any need of reflection.
What strikes me is, that while it's impossible to use an access modifier for the class, it is perfectly applicable to its members. Although neither one of them seems to make sense to me.
Regardless of the access modifier, still the only way to access the
field from outside the scope of this method, is using reflection.
Correct. However if you encounter this issue then the class really shouldn't be a local class.
Regardless of the access modifier, the field can always be accessed
inside the scope of the method, even when the field is private without
any need of reflection.
The use cases for local classes are few and far between. Access modifiers don't really have any impact since your class should be local to the method that created it:
Like member classes, local classes are associated with a containing
instance, and can access any members, including private members, of
the containing class.
http://docstore.mik.ua/orelly/java-ent/jnut/ch03_11.htm
Edit:
It may seem strange that the compiler allows you to specify a modifier that it then doesn't enforce. I can think of 2 good reasons why this might be the case:
There is a standard class format regardless of the scope of the class.
It allows you to show how you intend the member to be accessed, it would probably be a bad idea to access private fields/methods even though it's not syntactically wrong to do so.
I've always wondered. I have this Vertex class that's part of a generic Graph class. This Vertex class owns an object that's an entity. In my system everything happens trough the Vertex, you can't directly access the entity object with a getter. I realized though that I had to create public methods in my entity class so they can be called from the Vertex class. Is there a way to only expose methods to a class that owns said object?
Because right now I can instantiate an Entity and use it's public methods, but it doesn't make sense outside of the Vertex class. I don't know if there's a pattern or something people do to only let owners use methods of whatever they hold.
I'm using Java right now, but C++ is fine too. I believe in C++ you can use the friend keyword.
//Vertex.java
public class Vertex
{
private NodeDrawable _node;
...
}
//NodeDrawable.java
public class NodeDrawable
{
private disable();
}
I'd like to make Vertex the only class that's allowed to access NodeDrawable methods. Inner classes are cool, but I don't like having multiple classes in a single file.
First, I would ask myself if it is feasible to expose the Entity class at all. After that, you can make the Entities methods private, your Vertex class can still access them and everybody else don't - compares to protected methods which could be accessed by classes in the same source code package.
Edit
You will have to choose the access modifiers out of the Java possibilities and Java does not enable you to specify a single "friend" class - the Java way of doing this are inner classes.
One should have minimal required access to the object and its elements. If you don't require access to entity and it makes sense to have it's access through Vertex only, Make all object handles and methods private within Vertex.
I think want you want is simulate the c++ friend modificator in java look at this this question. Hope it helps.
You can use an inner class. The inner class has access to its containing class' variables and methods, and vice-versa. If you would like only the outer class to have access to the inner class, you can make the inner class private. Then not even other classes in the same package could call Outer.Inner (or in your case, Vertex.Entity). See docs.oracle.com/javase/tutorial/java/javaOO/nested.html
I am looking at other peoples' code.
I see a class with no non-static fields but in which most of the methods are non-static, requiring you to make an object to access methods that effectively operate statically.
Is there a possible reason for this, that I am just not understanding?
EDIT
Someone asked for examples. Here is some more info.
For instance there is a file manager class. The only fields are static and are Comparators. There are some methods to do things like sort files in a list, count files, copy files, move files to an archive folder, delete files older than a certain time, or create files (basically take a base name as string, and return a File with given base name and date/time tacked on the end.)
9 non-static methods
5 static methods
I don't see a particular rhyme reason for the ones that are static vs non.
One particularly odd thing is that there are two methods for removing files. One that removes a file no matter what, and one that only removes it if it is empty. The former is a static method while the latter is not. They contain the same exact code except the later first checks if the file.length is 0.
Another odd one is a class that does encryption - all fields and methods are static but it has a constructor that does nothing. And an init() method that checks if a static variable contains an object of itself and if not instantiates an object of itself into that field that is then never actually used. (It seems this is done with a lot of classes - init methods that check for an object of itself in a static variable and if not instantiate itself)
private static File keyfile;
private static String KEYFILE = "enc.key";
private static Scrambler sc;
It has methods to encrypt and decrypt and some methods for dealing with key and file.
Does this make sense to anyone? Am I just not understanding the purpose for this stuff? Or does it seem weird?
Objects don't have to have state. It's a legitimate use case to create an instance of a class with only behaviour.
Why bother to create an instance ? So you can create one and pass it around e.g. imagine some form of calculator which adheres to a particular interface but each instance performs a calculation differently. Different implements of the interface would perform calculations differently.
I quite often create classes with non-static methods and no members. It allows me to encapsulate behaviour, and I can often add members later as the implementation may demand in the future (including non-functionality related stuff such as instrumentation) I don't normally make these methods static since that restricts my future flexibility.
You can certainly do it that way. You should look carefully at what the instance methods are doing. It's perfectly okay if they're all operating only on parameters passed in and static final static class constants.
If that's the case, it's possible to make all those methods static. That's just a choice. I don't know how the original developers would justify either one. Maybe you should ask them.
Let me rephrase this question a bit,
Even though methods are non-static why would one declare fields as static?
I have taken below quoting from Java Docs,
Sometimes, you want to have variables that are common to all objects. This is
accomplished with the static modifier. Fields that have the static modifier in their declaration are called static fields or class variables. They are associated with the class, rather than with any object. Every instance of the class shares a class variable, which is in one fixed location in memory. Any object can change the value of a class variable, but class variables can also be manipulated without creating an instance of the class.
For example, suppose you want to create a number of Bicycle objects and assign each a serial number, beginning with 1 for the first object. This ID number is unique to each object and is therefore an instance variable. At the same time, you need a field to keep track of how many Bicycle objects have been created so that you know what ID to assign to the next one. Such a field is not related to any individual object, but to the class as a whole.
For Bicycle example, kindly refer the Java Docs.
Making all methods non-static allows you to override them. This makes it a lot easier to use this class in testing, because instead of the actual implementation you can use a mock that behaves as you want it for the tests. Static methods are, in my book, a code smell and should be avoided unless there's a good reason (e.g. quite trivial utility methods).
Also, at some point in the future you might want to change the behaviour of the methods in some situation, e.g. in the form of a strategy.
In the case of your encryption class, you might want to hand your class an instance of the encryption class to handle encrypting/decrypting, but be able to configure the details in some other place. That would allow you to change the algorithm and much more easily test your own code without also having to test the encryption.