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...");
        }
    }

提前致谢!

4

1 回答 1

4

您的Parent类引用是指Child类对象:

Parent polymorphicInstance = new Child();

因此,当您在 call 方法中传递引用时,实际调用的方法是仅具有Parent参数类型的方法。但是当你调用方法时doSomething(),在引用上:

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

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


这是多态的经典案例。假设您有一个类Shape和一个子类Circle,它覆盖了ShapecalculateArea()中定义的方法。

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

当您在子类中覆盖超类方法时,调用的实际方法将在运行时根据您的超类引用指向的实际对象决定。这称为方法调用的动态分派

于 2013-08-02T17:36:02.417 回答