调用超类方法而不是子类方法

时间:2015-07-05 12:56:38

标签: java inheritance polymorphism override

我们来看看这段代码:

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

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

3 个答案:

答案 0 :(得分:2)

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

  

在类C中声明或继承的实例方法mC覆盖来自C类A中声明的另一个方法mA,iff以下所有条件都为真: / p>      

      
  • A是C的超类。

  •   
  • C不会继承mA

  •   
  • mC的签名是mA签名的子签名(第8.4.2节)。

  •   
     

...

this section定义了方法签名:

  

两个方法或构造函数M和N具有相同的签名,如果它们具有相同的名称,相同的类型参数(如果有的话)(第8.4.4节),并且在调整之后形式参数类型N为M的类型参数,形式参数类型相同。

     

方法m1的签名是方法m2签名的子签名,如果是:

     
      
  • m2m1具有相同的签名,或

  •   
  • m1的签名与m2签名的删除(§4.6)相同。

  •   

答案 1 :(得分:1)

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

由于子类没有覆盖此方法(它没有相同的参数类型),因此父类的foo方法是在运行时执行的方法。

答案 2 :(得分:0)

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