0
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 类时出现错误。谁能解释一下这背后的原因?更具体地说,问题是为什么方法不能接受期望基类型的子类型参数?谢谢!

4

2 回答 2

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 { }

两者都AppleBananaFruitApple不是BananaBanana不是Apple。所以,你不能真的给Banana期待 的人Apple,但给只是期待 a 的人提供 aBanana或 an是有效的。AppleFruit

所以,

public void method(Fruit fruit) {

没有相同的签名

public void method(Apple apple) {

因为,如果是这样,那将意味着以下具有与上述相同的签名

public void method(Banana banana) {

并且签名必须在覆盖(实现)方法时匹配。

于 2012-07-10T06:10:22.447 回答
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

    }
}

最终,泛型版本与第一个选项完全相同,即编译器综合生成桥方法。如果你反编译你的类,你会注意到它就是这样做的。

于 2012-07-10T06:10:52.350 回答