【问题标题】:A superclass method is called instead of the subclass method调用超类方法而不是子类方法
【发布时间】:2015-07-05 12:56:38
【问题描述】:

让我们看看这段代码:

public class ParentClass {
    public void foo(Object o) {
        System.out.println("Parent");
    }
}

public class SubClass extends ParentClass {
    public void foo(String s) {
        System.out.println("Child");
    }

    public static void main(String args[]) {
        ParentClass p = new SubClass();
        p.foo("hello");
    }
}

我希望这会打印出“孩子”,但结果是“父母”。 java为什么要调用超类,我该怎么做才能让它调用子类中的方法?

【问题讨论】:

    标签: java inheritance polymorphism overriding


    【解决方案1】:

    SubClass#foo() 不会覆盖ParentClass#foo(),因为它没有相同的形参。一个接受Object,另一个接受String。因此不应用运行时的多态性并且不会导致子类方法执行。来自Java Language Specification

    在 C 类中声明或继承的实例方法 m<sub>C</sub>覆盖 C 中在 A 类中声明的另一个方法 m<sub>A</sub>,如果满足以下所有条件:

    • A 是 C 的超类。

    • C 不继承 m<sub>A</sub>

    • m<sub>C</sub> 的签名是m<sub>A</sub> 签名的子签名(第 8.4.2 节)。

    ...

    this section 定义了方法签名:

    两个方法或构造函数,M 和 N,如果它们具有相同的名称、相同的类型参数(如果有)(第 8.4.4 节),并且在适应N的形参类型与M的形参类型相同。

    m<sub>1</sub> 方法的签名是m<sub>2</sub> 方法签名的子签名,如果:

    • m<sub>2</sub>m<sub>1</sub> 具有相同的签名,或者

    • m1 的签名与 m<sub>2</sub> 签名的擦除(第 4.6 节)相同。

    【讨论】:

      【解决方案2】:

      父类没有签名为public void foo(String s)的方法。因此,在编译时,编译器只能选择public void foo(Object o)方法来执行p.foo("hello")

      由于子类没有重写这个方法(它没有相同的参数类型),父类的foo方法是在运行时执行的。

      【讨论】:

        【解决方案3】:

        字符串是java中的对象,正如前面所说的,它没有被覆盖,但是当你传递一个字符串时,它将运行第一个可以作为参数的可用方法,在这种情况下它是超类的方法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-10-24
          • 1970-01-01
          • 2015-03-01
          • 1970-01-01
          • 2013-04-14
          • 2018-01-22
          • 2012-04-18
          相关资源
          最近更新 更多