What happens when a superclass has a field marked final, but a subclass overrides (hides?) this field? 'Final' doesn't stop this, does it?
The specific example I'm working on is a Building class, from which different kinds of buildings inherit. The cost of each type, among other things, should be final to each subclass, but each type of building should have their own cost.
Edit: I've since realized that I had no idea what I was talking about above. What I really want are static variables of cost. However, if I declare these static variables in the superclass, they are static to the superclass, so Subclass1.cost, e.g., refers to the same value as Superclass.cost or Subclass2.cost. How can I make variables that are static to each subclass, without having to declare them in each class.
The final
keyword, when applied to fields of a Java class, has nothing to do with inheritance. Instead, it indicates that outside of the constructor, that field cannot be reassigned.
Java treats name hiding and overriding separately. Overriding actually changes the observable behavior of the program at runtime by switching which function is called, while name hiding changes the program by changing the static interpretation of which field is being reference. final
as applied to overriding only works for methods, because fields in Java cannot be overridden. The use of final
in these different contexts is a bit confusing, unfortunately, and there is no way to prevent a field from having its name hidden in a subclass.
If you want the buildings to have different costs, one option would be to have an overridden getCost
method which is overridden differently in each derived class. Alternatively, you could have a single protected
or private
field in the base class that stores the cost, then have each subclass set this field either directly (if this is protected
) or through a base class constructor (if this field is private
).
Hope this helps!
You can do this two ways: make an accessor function and hide the field itself or else pass the building cost to the superclass constructor from the subclass. You can combine these and make a property that can't be overridden by subclasses:
public class Building {
private final int cost;
protected Building(int cost, ...) {
this.cost = cost;
}
public final int getCost() {
return cost;
}
}
public class Cottage extends Building {
public Cottage() {
super(COTTAGE_COST, ...);
}
}
Agree with other answers, but I think the following implementation is better in this case:
public abstract class Building {
private final int cost;
public Building(int cost) {
this.cost = cost;
}
public final int getCost() {
return cost;
}
}
class Skyscraper extends Building {
public Skyscraper() {
super(100500);
}
}
Of course the field could be made public, but that's the other story...