In both super class A and sub class B i have variable abc as 10 and 20 respectively, and a method callme(), overrided in sub class.
If i do
A a = new B();
B b = B(new A());
then if i write
a.callme() -> calls B's method
b.callme() -> calls A's method.
This is because method is called based upon the actual object.
If i do
str = a.abc; // will print 10 , based upon ref var type A
str = b.abc; // will print 20 , based upon ref var type B
Why is this difference? Why not both method and variabl开发者_如何学Ces accesses based upon the actual object?
Thanks
Remember, instance variables are never overidden, they are hidden. It is the type of reference that decides that whose instance variables will be accessed.
In subclass, the method callme()
is overidden. So, according to Dynamic method dispatch mechanism, it is the type of object that decides which method will be called at Runtime. It is because, objects are created at runtime.
E.g
class A {
int abc = 10;
public void callme() {
System.out.println("In class A");
}
}
class B extends A {
int abc = 20; // hidden, not overidden
public void callme() {
System.out.println("In class B");
}
public static void main(String [] args) {
A a = new A();
a.callme(); // calls A's callme() method.
B b = new B();
b.callme(); // calls B's callme() method.
}
}
Methods have an implementation while fields just store values/objects. It makes sense to be able to override the implementation of a method. But I don't see a need for "overriding" a field. Why don't just remove the declaration from the subclass and use the field of the superclass?
On the other hand it is also possible to hide methods. But you have to make them private.
class OuterClass {
void test() {
InnerSubClass isc = new InnerSubClass();
isc.m(); // prints "In subclass"
((InnerSuperClass) isc).m(); // prints "In superclass"
}
class InnerSuperClass {
private void m() {
System.out.println("In superclass");
}
}
class InnerSubClass extends InnerSuperClass {
private void m() {
System.out.println("In subclass");
}
}
}
精彩评论