以下程序打印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()");
}
}
答案 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
父实体的实现。当您使用与超类中的方法具有相同签名的方法定义方法时,会简要概述事物的处理方式:
在子类中,您可以重载从超类继承的方法(如第一个示例中所示)。这样的重载方法既不隐藏也不覆盖超类实例方法 - 它们是新方法,对于子类是唯一的。
覆盖方法时,您可能希望使用@Override
注释来指示编译器您要覆盖超类中的方法。 如果由于某种原因,编译器检测到该方法在其中一个超类中不存在,那么它将生成错误 。