This is probably answered somewhere, but I have no idea what to search for. Imagine you have the following...
The superclass, Animal.java
public class An
All non-static methods in java are by default "virtual functions". Unless they're marked as final (which makes the method not overridable). Java uses a virtual method table to call the correct object's method.
You can not override fields, new declaration of noise
in Lion
hides parent's noise
attribute. do like this:
public class Lion extends Animal {
// public String noise = "ROAR!!"; // <---- Remove this line
public Lion() {
noise = "ROAR";
}
public String toString() {
return noise;
}
}
This is because Java talks only about method overriding. Member variables can only be shadowed in child class. So when you say c.noise it actually refers to the string variable in parent class as the c if reference type Animal.
Short answer:
You can override methods, but it's not possible to override fields.
Long answer:
Each class sees the methods and fields of it's own and of it's parents (except for private methods). If the child delcares a method, whose name is the same, as the name of the method in his parent class, this method becomes overridden - if this method is somehow invoked on the child instance (even from the one of the parent's methods), the brand new method will be used instead of the parent's one. Child may still call the original method of his last parent via super.method(...)
call.
But the story is different when we come to the fields. If the child declares a new field, that is named exactly as the field in parent class, it will simply hide the parent's field without overriding, just like the local variable hides global one. So the child methods will simply see the child's fields, but the parent's method will continue to see parent's field, and child's field will not be visible by any means from the parent class - that's what you've got.
Child can access the field of it's parent via ((Parent)this).field
.
The topics you are interested in are Dynamic Dispatch and Virtual Method Table. Basically, by design, Java allows for methods to be overridden (assuming they are non-final) and at run time the JVM will execute the appropriate implementation. This polymorphic attribute is only afforded to methods. Good OO design would dictate the fields be encapsulated anyway.
Longer answer:
So really the way you'd do this is define Lion thus:
public class Lion extends Animal {
public Lion() {
noise = "ROAR!!";
}
}
So now for Lion instances the noise member variable of Animal has been updated to ROAR!!
Of course you'd (almost) never actually have a public mutable member on a class like that in the wild.