public abstract class AbstractClass
{
public abstract void AbstractClassMethod();
}
public class DerivedClass extends AbstractClass {
@Override
public void AbstractClassMethod() {
// TODO Auto-generated method stub
}
}
public interface InterfaceObject
{
public void InterfaceObjectMethod(AbstractClass oAbstractClass);
}
public class TestAbstractParam implements InterfaceObject {
@Override
public void InterfaceObjectMethod(AbstractClass oAbstractClass) {
// TODO Auto-generated method stub
}
}
public class TestDerivedParam implements InterfaceObject {
@Override
public void InterfaceObjectMethod(DerivedClass oDerivedClass) {
// TODO Auto-generated method stub
}
}
编译TestDerivedParam类时出错。任何人都可以解释一下这背后的原因吗? 更具体地说,问题是为什么方法不能接受期望基类型的子类型参数? 谢谢!
答案 0 :(得分:1)
在TestDerivedParam
方法中
public void InterfaceObjectMethod(DerivedClass oDerivedClass) {
与
不同public void InterfaceObjectMethod(AbstractClass oAbstractClass);
InterfaceObject
中的。
您正在使用@Override
注释,但未使用相同的方法签名。
更具体地说,问题是为什么方法不能接受期望基类型的子类型参数?
请参阅以下示例:
public class Fruit { }
public class Apple extends Fruit { }
public class Banana extends Fruit { }
Apple
和Banana
都是Fruit
,但Apple
不是Banana
而Banana
不是Apple
。因此,您无法真正将Banana
提供给期望Apple
的人,但是对于只有Banana
或Apple
的人来说是有效的期待Fruit
。
所以,
public void method(Fruit fruit) {
与
没有相同的签名public void method(Apple apple) {
因为,如果是,则表示以下内容具有与上述相同的签名
public void method(Banana banana) {
签名必须匹配,同时覆盖(实现)方法。
答案 1 :(得分:0)
您正在更改方法的签名,因此,Java只能假设您的意图是“重载”具有相同名称和不同参数的现有方法。
您也可以使用桥接方法:
@Override
public void InterfaceObjectMethod(AbstractClass oDerivedClass) {
// TODO Auto-generated method stub
}
public void InterfaceObjectMethod(DerivedClass oDerivedClass) {
InterfaceObjectMethod((AbstractClass)oDerivedClass);
}
第二种方法是桥接方法,它的职责是将请求转发给实际的继承方法。正如您所看到的,桥接方法是重载,而不是覆盖。
另一种选择是使用泛型。
interface InterfaceObject<T extends AbstractClass>
{
public void InterfaceObjectMethod(T oAbstractClass);
}
class TestAbstractParam implements InterfaceObject<AbstractClass> {
@Override
public void InterfaceObjectMethod(AbstractClass oAbstractClass) {
// TODO Auto-generated method stub
}
}
class TestDerivedParam implements InterfaceObject<DerivedClass> {
@Override
public void InterfaceObjectMethod(DerivedClass oDerivedClass) {
// TODO Auto-generated method stub
}
}
最终,泛型版本与第一个选项完全相同,也就是说,编译器会综合生成桥接方法。如果您对类进行反编译,您会发现它确实如此。