问题
class A{
int a=10;
public void show(){
System.out.println("Show A: "+a);
}
}
class B extends A{
public int b=20;
public void show(){
System.out.println("Show B: "+b);
}
}
public class DynamicMethodDispatch {
public static void main(String[] args) {
A aObj = new A();
aObj.show(); //output - 10
B bObj = new B();
bObj.show(); //output - 20
aObj = bObj; //assigning the B obj to A..
aObj.show(); //output - 20
aObj = new B();
aObj.show(); //output - 20
System.out.println(bObj.b); //output - 20
//System.out.println(aObj.b); //It is giving error
}
}
In the above program i'm getting Error wen i try invoking aObj.b.
1.why i'm not able to acess that variable through the aObj though it is refering to class B??
2. why i'm able to acess the method show()?
回答1:
You have to distinguish between the static type of aObj
and the runtime type of aObj
.
Code such as
A aObj = new B();
results in an aObj
variable with static type A
and runtime type B
.
The compiler will only bother too look at the static type when deciding what to allow or not.
To your questions:
1.why i'm not able to acess that variable through the aObj though it is refering to class B??
Because there is (in general) no way for the compiler to know that aObj
will refer to a B
object at runtime, only that it will refer to some form of A
object. Since .b
is not available on all A
objects, so the compiler will think "better safe than sorry" and disallow it.
2.why i'm able to acess the method show()?
Because this method is available in all A
objects (if it's not declared in the subclass, it is still inherited from A
).
回答2:
aObj
is a local variable of type A
. A
has no member called b
, that's only in your subclass B
. If you want to use b
, you need to declare a variable of type B
, but of course you can only assign it instances of B
(or subclasses if there are any).
A
declares a method show()
, but you override the implementation in your subclass B
.
回答3:
This behavior is known as virtual method invocation
, and it is an important aspect of polymorphism
in Java. You should have a look at this tutorial.
回答4:
class A{ // class A has variable a and method show();
int a=10;
public void show(){
System.out.println("Show A: "+a);
}
}
class B extends A{ //class B inherits variables and methods of A.
// so class B has variable a, b and show(). Also, show is overridden by class B.
public int b=20;
public void show(){
System.out.println("Show B: "+b);
}
}
since A doesn't have variable b inside it, even when u are passing B to A, you still have A object which does not have variable b inside it. So, trying to access b will give you compile time error.
in case of show(), A and B both have this method, so what you are doing here is actually overriding it at runtime. This is nothing but Polymorphism. So since A already has method show(), and it is overridden later by B,
A a = new B(); a.show();
this will run the show() method of B at runtime.
回答5:
Methods and fields have different polymorphic behaviour.
The method that will be called is the method of the run time type of the instance
aObj=new B(); //new B()
The field that will be called is the field of the type of reference that you declared
A aObj = new A(); // A aObj
The following would work even is there was no show() method in A.
aObj = new B();
aObj.show(); //calls B's show()
来源:https://stackoverflow.com/questions/10595527/dynamic-method-dispatch-in-java