假设我们有下一个情况:
父类A:
class A{
public A(){}
public doSomething(){
System.out.println(this.getClass());
}
}
带着孩子B级:
class B extends A{
public B(){}
public void doSomething(){
super.doSomething();
System.out.println(this.getClass());
}
}
和主要课程:
class Main{
public static void main(String[] args){
A ab=new B();
ab.doSomething();
}
}
当我执行此代码时,结果是
B
B
当引用属于A类时,为什么超类A中引用的this
会将B
作为类返回?
答案 0 :(得分:16)
引用是什么并不重要,它是实例化对象的类。您正在创建的对象是B类型,因此this.getClass()始终返回B.
答案 1 :(得分:3)
尽管你正在调用doSomething()
的{{1}}方法,但该调用期间的A
是this
,因此B
方法是getClass()
而不是B
。基本上A
始终是this
,无论您使用的是超类B
中的方法,来自A
的方法,还是来自B
的超类{ {1}}(所有Java类的父类)。
答案 2 :(得分:1)
this
在这个故事中对你没有任何帮助。致电this.getClass()
与仅呼叫getClass();
所以,A调用getClass(),如果你正在处理扩展A的B实例,它将返回B.
答案 3 :(得分:1)
从运行时与静态类型的角度来考虑它:
Animal a = new Cat();
变量a
的静态类型(在本例中写在左侧)是Animal
(您无法将Cat
传递给需要a
的方法downcast)但Cat
指向的对象的运行时类型为a.getClass()
。
foo(Cat c);
foo(Animal animal)
公开运行时类型(如果它有助于将其视为最具体的子类型)。
有趣的是,Java重载方法在编译时被解析(没有查看运行时类型)。所以给出了以下两种方法:
foo(a)
调用{{1}}会调用后者。为了“修复”这个,访问者模式可以用于根据运行时类型(双重调度)进行调度。
答案 4 :(得分:0)
程序输出正确。
在Main class ab.doSomething()中; line get执行类B的doSomething()方法然后调用super.doSomething(); line将调用类A的doSomething()方法。因为此关键字指示当前对象的引用(ab是类B的对象,请参阅A ab = new B();因为构造函数是类B),即System.out.println (this.getClass()); A类中的行仅打印B.
再次控制将返回System.out.println(this.getClass());在B类中,所以再次B将获得打印。
在birdeye视图中,只创建了B类的对象。这就是我们输出B B的原因。