问题
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