问题
Suppose that we have next situation:
Parent class A:
class A{
public A(){}
public doSomething(){
System.out.println(this.getClass());
}
}
with a child class B:
class B extends A{
public B(){}
public void doSomething(){
super.doSomething();
System.out.println(this.getClass());
}
}
and Main class:
class Main{
public static void main(String[] args){
A ab=new B();
ab.doSomething();
}
}
When I execute this code result is
B
B
Why does this
, referenced in superclass A, returns B
as a class when the reference is of type A?
回答1:
It doesn't matter what the reference is, it's the instantiated object's class that counts. The object that you're creating is of type B, therefore this.getClass() is always going to return B.
回答2:
Despite the fact that you are calling the doSomething()
method of A
, the this
during that call is a B
, and so the getClass()
method is called on B
not on A
. Basically the this
will always be a B
whether you are using a method from superclass A
, a method from B
, or from A
's superclass Object
(the parent class of all Java classes).
回答3:
this
doesn't do anything for you in this situtaion. Calling this.getClass()
is no different than just calling getClass();
So, A calls getClass(), which will return B if you are dealing with an instance of B that extends A.
回答4:
Think of it in terms of runtime vs static types:
Animal a = new Cat();
The static type (in this case written on the left hand side) of variable a
is Animal
(you couldn't pass a into a method that required a Cat
without a downcast) but the runtime type of the object pointed to by a
is Cat
.
a.getClass()
exposes the runtime type (if it helps think of it as the most specific subtype).
Interestingly in Java overloaded methods are resolved at compile-time (without looking at the runtime type). So given then following two methods:
foo(Cat c);
foo(Animal animal)
Calling foo(a)
would call the latter. To 'fix' this the visitor pattern can be used to dispatch based on the runtime type (double dispatch).
回答5:
The output of program is correct.
When in Main class ab.doSomething(); line get executed doSomething() method of class B will be called then super.doSomething(); line will call doSomething() method of class A. As this keyword indicates reference of current object(ab is the object of class B see A ab=new B(); as constructor is of class B),i.e.System.out.println(this.getClass()); line in class A will print B only.
Again control will come back to System.out.println(this.getClass());in class B, So again B will get print.
In birdeye view only object of class B has created. That is why we are getting B B in output.
来源:https://stackoverflow.com/questions/5155811/inheritance-and-the-this-keyword