[英]Casting to Superclass, and Calling Overriden Method
我有下一个问题。 我扩展了Parrent
类,并在Child
类中重写了其中的一种方法。 我试图将类型转换为超类类型,但是每次都得到孩子的重写方法。 当我使用多态时,也会发生这种情况。
问题在下面的代码内部注释中……谢谢。
class Parrent{
public void test(){
System.out.println("parentTest");
}
}
class Child extends Parrent{
@Override
public void test(){
System.out.println("childTest");
}
}
class StartProgram{
public static void main(String[] args) {
Parrent p1 = new Parrent();
p1.test(); // output: parentTest
Child c1 = new Child();
c1.test(); // output: childTest
Parrent p2 = new Child();
p2.test(); // why returns child method? becouse it's overriden?
((Parrent) new Child()).test(); // why returns child method if I cast it?
}
}
强制转换仅是为了编译器的利益。 JVM对此一无所知,并且不影响调用什么方法。 JVM尝试通过查找与给定签名匹配的东西来解析方法,从最具体的类开始,然后沿层次结构朝根(java.lang.Object)向上移动,直到找到某个东西为止。
多态性的目的是使调用某个对象的代码不必确切知道正在使用的子类,被调用的对象将承担其自身的特殊功能。 子类重写方法意味着该子类的对象需要以自己的特定方式处理该方法,并且调用者不必关心它。
强制转换适用于您的代码不知道某种类型的异常情况。 如果您知道超级类型(在您的示例中为父类),则无需强制转换,子类应自行处理。
实际的类型是Child,因此在调用方法时,将调用Child的方法。 引用类型是否为Parent无关紧要,重要的是对象的实际类型。
您也不能“强制转换为超类”来调用Parent的方法。
方法解析发生在运行时,而不是编译时。 对象的类(其行为)声明了方法的实现,因此可以使用它。
能够按其超类引用对象是OOP的本质。
参见Liskov替代原理
这里调用child方法是因为函数在运行时绑定,并且在您的参考内存中是child
((Parrent)new Child())。test(); // new Child()表示内存属于孩子
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.