I've created an abstract class contains a method with an implementation. This method is called by subclasses to populate a list, which should be shared amongst all instances of each individual subclass (like an abstract static field which is different and static to each subclass). The issue is: abstract static fields do not exist, so how else might I be able to achieve this behaviour?
For context, the implemented method on the abstract class is for resolving classes from an unqualified name via the reflections8 package. This method calls an abstract method to get the packages to reflect, which just returns a String[] (as subclasses will want to search in different packages). This method then generates a Map<String, Class<?>> containing a mapping of the name of each reflected class to the Class, which is what I would like to share between instances of each specific subclass type (so that it doesn't have to reflect for the same subclass more than once). Ultimately, this method is called by the subclass in order to instantiate a class from its unqualified name.
Please forgive me if this is a rather strange way of doing things; I come from the land of iOS where we don't have package names attached to class names (so I can just call NSClassFromString("ClassName") and that's it).
EDIT: Check out this gist for the current implementation (and check out the comment for a usage example).
My thoughts: if you're wanting your subclasses to have their own respective static fields, it's best to just have those static fields declared in them rather than this abstract class.
From what I understand, your abstract class is really just a placeholder for this one implemented method. Do any of your subclasses override anything from the parent? If not, maybe it doesn't need to be an abstract class.
Plus, does your abstract class need any state? Because if not, you might be better off with this: change your abstract class to be a static class, and your implemented method be a static method, which accepts an "ClassName" argument. Then in your subclasses you can just directly call the method with your subclass' static fields using something akin to MyStaticClass. NSClassFromString(subclassStaticField);
There is no equivalent for abstract static for fields:
An instance field cannot be abstract. It really makes no sense. abstract means we are deferring some of the details to a subclass. But for an instance field there is nothing that it makes sense to defer.
A static field is not inherited anyway, so there is no way one could be used polymorphically. static fields with the same name in different classes are distinct variables.
You can (of course) use reflection to test if a field (static or instance) has been declared ... but that's not what abstract means in Java.
Solution:
If you want an instance field to exist in all of the subclasses of an abstract class, declare it as a regular field in the abstract class.
If you want a static field to exist in all subclasses, you have no choice but to explicitly declare it in each subclass. You won't be able to use it / them polymorphically.
Related
I am creating an interface with many implementing classes and there is an attribute they must all have;
I guess it's better to put that attribute in their interface than writing many constructor lines, but attributes can only be static final and require to be immediately initialized.
public interface Interface{
static final AttrType attribute = new AttrType( *something* );
I have 2 problems: this attribute is a class and its constructor needs some other type parameters not just ints, and also it shouldn't be initialized here, I need all implementing classes of the interface to work on the same instance of AttrType which as i said I won't instantiate in the interface.
So, as I am not expert enough, is there a way to do this in the interface or I should just write a line in every subclass' constructor to put in the one AttrType instance they need?
Java interfaces describe what a class can do, rather than what a class is. Therefore, an interface only describes methods.
You could handle this in a few ways:
Using an interface, you could have a getter for the variable, which would force the implementing classes to have the variable. Something like "public AttrType getAttribute();"
Or you could create a class, probably abstract, which implements the interface and has the variable, and its getter and setter. The subclasses all would inherit this variable and behavior.
Would it be possible to add also a common base class to go with your common interface which all the classes could inherit? Then the common base class constructor could contain the attribute instance. Also you could consider using an abstract class instead of interface.
The title is not quite clear, but I didn't see how to explain it in a short sentence.
I have an interface myInterface (This must be an interface, not an abstract, because enum will implement it).
I expect to have an attribute myAttribute (integer) which is not reachable from outside, except for the derivated classes from the interface (protected).
I want a method myMethod that contans myInterface as input parameter. But then, I have trouble when I try to implement it.
The method looks like this
boolean myMethod(myInterface interface)
{
return this.myAttribute>interface.myAttribute;
}
I can't define "myAttribute" as protected in "myInterface".
If I don't define "myAttribute" in "myInterface", I can't use it in the definition of myMethod, when I implement it in my derivated class : The signature should contain "myInterface" as input parameter, and this one doesn't have any "myAttribute" attribute.
The only solution I have now is to cast "myInterface" in its derivate, but I don't like it (Globally, I don't like casts). Does anyone has another idea?
You cannot.
Interfaces can only define (implicitly) public static final variables, otherwise said, public constants.
What you should do is define a method returning your attribute in your interface, which in turn, its implementing classes will be forced to implement (if they're not abstract).
The method will be implicitly public.
This will also enforce the encapsulation of the variable within the implementing classes.
You can then retrieve the value by virtually invoking the getter method on the interface: myInterface.getMyAttribute().
Edit
If your scope is to not be able to access the value an instance field outside classes that implement a common interface at all, you can proxy you hierarchy by having an abstract class in between the interface and your implementing classes.
In turn, the abstract class would implement none of the interface methods (hence still forcing the concrete classes to implement all), but instead feature a protected attribute that the concrete classes would all have access to.
Finally the concrete classes could decide whether or not to let other classes access that field.
This question is mainly in reference to Luiggi's answer to this SO question:
Why can you not inherit from a class whose constructor is private?
I understand that Java enforces that every subclass constructor must call one of its superclass's constructors. If all the superclass's constructors are private, this is obviously not possible. So, if a subclass theoretically could inherit from a superclass with private constructors, the result would be that you couldn't call a constructor on the subclass.
But what if I never intend to create an instance of the subclass anyway? For example, what if my subclass only adds static fields and methods, and I'm only interested in using the static fields and methods of the superclass? Then I don't need a constructor for the subclass.
what if my subclass only adds static fields and methods, and I'm only
interested in using the static fields and methods of the superclass
In that case you don't need inheritance - use composition!
You should seal your class by declaring it as final. Then it is guaranteed that no sub-classes can be made
If only adding subclasses and can only create the parent class, the child "class" is really just a helper class without adding any functionality/responsibilites/etc. to the parent. In many respects, it's meaningless.
A subclass of this sort would not be a legitimate subclass. Even if all of its fields and methods were declared static, it would inherit all of the fields and methods of all of its superclasses, all the way back up to Object. And there are non-static methods in Object. So this subclass would have some set of non-static methods (and possibly fields) in its declaration.
This subclass could then be used as a type of a field, variable, type parameter or method argument (i.e. anywhere a type can be used). The compiler would have to keep track of the fact that this particular type could only be used in some restricted sense. (Imagine a method that returned a value of this subclass for example).
There are, I'm sure, many more gotcha's for this sort of thing.
So, bottom line, it would make writing a compiler really hard.
What do we we call a constructor, if it is not a member of a class as stated in Oracle doc: http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
I think the term "member" was defined to exclude constructors for the sake of convenience. Constructors, even public ones, are not inherited; members are inherited (unless they are static and/or private). It would be awkward when talking about the rules of inheritance to always have to say "members except constructors".
From the Java Language Specification, ยง8.2:
Constructors, static initializers, and instance initializers are not members and therefore are not inherited.
Just call constructors "constructors".
Its a special method that every class has, which is called after creation of the object. in JVM its called using invokespecial so, lets just call it a special method?
And since there is just 1 special method in Java - they all call it "constructor"
All the doc is saying is that the constructor is not inherited by default. Since the constructor is a method that is invoked on the construction of the object in the memory heap, then once you create a subclass that inherits from a super class, the constructor of the super class is not invoked by default.
For instance if you have a class Vehicle and a subclass Car, assume the Vehicle constructor is as follows:
public Vehicle(String vehName) {
this.vehName = vehName;
}
Then, even though your class Car inherits from class Vehicle, the vehName member (field) will not be set as the constructor above does.
So you will need to do something like this:
public Car(String vehName) {
super(vehName);
}
Hope that helps
In Java, a class body (the area between braces) can contain the following key items: (1) Fields (2) Methods (3) Other Classes (nested classes) (4) Constructors (5) Initializers
An object created from a particular class shall take the shape that is similar to the blueprint (class) from which it's created. Now, if you look at items that can be contained in a class body, only item (1) to (3) help in determining what sort of object can be created from a particular class definition.
Constructors and initializers only play part in actual creation of the object (e.g. initialization of already defined fields), but do not determine what shape/state that object shall carry, and what behaviors it will display.
For this reason, to me, it make sense to call item (1) to (3) class members (i.e. class members are those items within a class body that determine how an object created from the class looks like and behave); whereas constructors and initializers are not members because their absence in a class definition does not affect a class state and behavior.
As such, only class members can be inherited as the whole point behind inheritance is to enable a subclass reuse state and behavior of its superclass.
A Constructor is a method which is in a class which is used to create a new instance of that class.
Being a member of a class just means that the item in question is in the class.
Constructor is a method which name is same as the class. It is used to initialize the object of class. It's implicit in action. Parametric constructor initialize object with different value.
I have an abstract java class that implements a couple of its methods, but not others. In the methods it implements it uses a private attribute variable. The variable used also needs to be used in a subclass.
As I see it my options are:
Declare the private variable in both the subclass and the super class
defer the implementation of the methods currently implemented in the abstract class to the subclasses
Are there other options? Which of these makes more sense and why?
The question is how you want to maintain your state: If it is of no concern, where the value is stored, you can just add a private member "on top" of the other and use that instead of the one in the superclass. If you want to have some methods from your superclass and some methods from your subclass to access the same state, you need to change visibility:
You could declare the variable as protected, making it accessible in the subclass, or implement accessor methods, or even make it public.
Hopefully the abstract class has been designed such that you shouldn't need access to the private fields. As to which of your two methods to use, that depends entirely on what the abstract class and your subclass are and what they're supposed to be doing.
If you only need read access to this variable and the superclass methods don't modify it, you can just add another (completely separate) private field of the same name/type to your subclass. If you're attempting to modify the behaviour of the superclass methods by changing the field, you're going to have to override the methods instead.