多态和重载

3

我希望有人能够解释一下这个决定是如何做出的。我知道,根据声明类型选择了过载版本,但是为什么在第二次调用时,决策是基于运行时类型呢?

    public class Test {
        public static void main(String[] args) {
            Parent polymorphicInstance = new Child();

            TestPolymorphicCall tp = new TestPolymorphicCall();
            tp.doSomething(polymorphicInstance);
            // outputs: Parent: doing something... 

            call(polymorphicInstance);
            // outputs: Child: I'm doing something too 
        }
        public static void call(Parent parent){
            parent.doSomething();
        }
        public static void call(Child child){
            child.doSomething();
        }
    }

    public class Parent {
        public void doSomething() {
            System.out.println("Parent: doing something...");
        }
    }
    public class Child extends Parent{
        @Override
        public void doSomething() {
            System.out.println("Child: I'm doing something too"); 
        }
    }

    public class TestPolymorphicCall {
        public void doSomething(Parent p) {
            System.out.println("Parent: doing something...");
        }
        public void doSomething(Child c) {
            System.out.println("Child: doing something...");
        }
    }

感谢您的提前帮助!
1个回答

4

您的父类引用指向子类对象:

Parent polymorphicInstance = new Child();

如果在调用方法时传递了引用,那么实际调用的方法只有使用Parent参数类型的那个。但是,当您在parent引用上调用doSomething()方法时:

public static void call(Parent parent){
    parent.doSomething();
}

它将调用你在 Child 类中覆盖的 doSomething() 方法。


这是经典的多态案例。假设你有一个 Shape 类和一个子类 Circle,它重写了 Shape 类中定义的 calculateArea() 方法。

Shape circle = new Circle();
// This will invoke the method in SubClass.
System.out.println(circle.calculateArea());

当你在子类中重写超类方法时,实际调用的方法是在运行时决定的,这取决于超类引用指向的实际对象。这被称为方法调用的动态分派。

谢谢,我因为这个棘手的例子有点困惑自己,因为TestPolymorphicCall类方法根本没有调用参数的引用。但是你是正确的,无论调用哪个重载版本的方法,都是基于声明类型进行选择,当涉及到多态类型时,所调用的行为是子类型行为。 - César Barbosa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接