我有一个父类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
,所以它不应该调用B
的doSomething(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的实例