为什么在这种情况下调用父类方法而不是子类



我有一个父类a和它的子类B。两者都有具有diff类型参数的doSomething方法。

A类

package Inheritance;
public class A {
    public void doSomething(Object str){
        System.out.println("Base impl:"+str);
    }
}

B类

package Inheritance;
public class B extends A{
    public void doSomething(String str){
        System.out.println("Child impl:"+str);
    }
    public static void main(String[] args) {
        A a = new B();
        a.doSomething("override");
    }
}

当我运行这个时,我会得到"Base-inpl:override"作为输出!

a指向B的一个对象,而他传递的参数是String,所以它不应该调用BdoSomething(String str)方法吗?

当您使用类型a的引用时,您只能看到为类a定义的方法。由于B中的doSomething不会覆盖a中的doSomething(因为它有不同的签名),因此不会调用它。

如果要使用类型为B的引用,两种方法都可用,并且会选择B的doSomething,因为它有一个更具体的参数(String vs Object)。

我想这不被认为是方法重写的情况,因为签名并不完全相同。在B.中将String参数更改为Object。

在类A中,您已经声明了一个方法doSomething(Object obj)。但是,在类B中,您已经声明了方法doSomething(String str),它的参数类型与类a中的参数类型不同。这意味着类B的doSomething不会覆盖类a的doSomething

要获得所需的输出,请执行以下操作(我省略了主要方法以获得更通用的代码示例):

public class A {
    public void doSomething(Object str){
        System.out.println("Base impl:"+str);
    }
}
public class B extends A {
    // Helpful annotation: It tells you
    // if you aren't overriding any known method
    @Override
    public void doSomething(Object str) {
        System.out.println("Child impl:"+str);
    }
}

如@Eran所说

当您使用类型a的引用时,您只能看到为类a定义的方法。由于B中的doSomething不会覆盖a中的doSomething(因为它有不同的签名),因此不会调用它

如果你想调用B中定义的方法,你需要将其强制转换为以下

((B)a).doSomething("override");

或者您必须隐式使用B的实例

最新更新