我有下一个问题。
我扩展了一个类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?
}
}
答案 0 :(得分:2)
Casting完全是为了编译器的利益。 JVM对此一无所知,也不会影响调用哪种方法。 JVM尝试通过查找与给定签名匹配的内容来解析方法,从最具体的类开始,然后沿着层次结构向根(java.lang.Object)前进,直到找到某些内容。
多态的目的是调用某些对象的代码不必确切地知道正在使用哪个子类,被调用的对象负责其自己的专用功能。让子类覆盖方法意味着该子类的对象需要以他们自己的特定方式处理该方法,并且调用者不必关心它。
Casting用于奇怪的边缘情况,你的代码无法知道什么类型的东西。如果您知道超类型(在您的示例中为Parent),则不需要强制转换,子类应该自行处理。
答案 1 :(得分:0)
实际类型是Child,因此当您调用方法时,将调用Child的方法。引用类型是否为Parent是无关紧要的,它是重要对象的实际类型。
你不能“强制转换为超类”以便调用Parent的方法。
答案 2 :(得分:0)
方法解析在运行时发生,而不是在编译时发生。对象的类(它的行为)声明了方法的实现,因此使用它。
能够通过超类引用对象是OOP的本质 见Liskov substitution principle
答案 3 :(得分:0)
这里调用子方法,因为函数在运行时绑定,在引用内存中是子
((Parrent)new Child())。test(); // new Child()表示内存属于子级