在子类中重载,意外行为

时间:2017-09-16 07:55:46

标签: java binding static override overloading

以下程序打印ParentClass a() -

public class StaticBindingTest {

    public static void main(String[] args) {
        ParentClass p = new ChildClass();

        p.a("abc");
    }       
}

class ParentClass{

    public void a(Object o){
        System.out.println("ParentClass a()");  
    }
}

class ChildClass extends ParentClass{

    public void a(String s){
        System.out.println("ChildClass a()");   
    }
}

但是,如果我将ParentClass a()更改为接受String,程序将打印Childclass a()。为什么? -

package com.my.test;

public class StaticBindingTest {

    public static void main(String[] args) {
        ParentClass p = new ChildClass();

        p.a("abc");
    }       
}

class ParentClass{

    public void a(String o){
        System.out.println("ParentClass a()");  
    }
}
class ChildClass extends ParentClass{

    public void a(String s){
        System.out.println("ChildClass a()");   
    }
}

2 个答案:

答案 0 :(得分:0)

在编译时决定调用方法的重载。调用方法的实现在运行时决定。

在第一种情况下,ChildClass基本上有两次a重载。一个接受String,一个接受Object

您的变量p的编译时类型为ParentClass。编译器实际上并不知道它实际上是ChildClass。那必须等到运行时间。所以编译器调查ParentClass并看到a中只有ParentClass的一个重载,所以它决定调用那个重载,因此输出。

在第二种情况下,a中的ChildClass有1次重载,但有2次实现。

编译器会像往常一样将p视为ParentClass,这一次,它会选择接受String的重载,这是唯一可以选择的重载。现在在运行时,调用a。由于p实际上是ChildClass实例,因此它会调用ChildClass中的实现,因此输出。

答案 1 :(得分:0)

原因是子类然后Override父实体的实现。当您使用与超类中的方法具有相同签名的方法定义方法时,会简要概述事物的处理方式:

enter image description here

在子类中,您可以重载从超类继承的方法(如第一个示例中所示)。这样的重载方法既不隐藏也不覆盖超类实例方法 - 它们是新方法,对于子类是唯一的。

覆盖方法时,您可能希望使用@Override注释来指示编译器您要覆盖超类中的方法。 如果由于某种原因,编译器检测到该方法在其中一个超类中不存在,那么它将生成错误