无法使用抽象参数的子类实现抽象方法

时间:2014-10-01 02:55:43

标签: java interface

说我正在创建一个实现接口的类,并且有这样的代码:

public void setGoalLocation(Location loc)
{
    goal = loc;
}

代码没有编译,因为它要求我实现一个" setGoalLocation(Ilocation loc)"方法,其中" Ilocation"是一个界面和"位置"是一个实现它的实际具体类。

这意味着我必须做这样的事情:

public void setGoalLocation(ILocation loc)
{
    goal = (Location)loc;
}

这看起来真的很尴尬。有趣的是,Java似乎并不关心返回Location而不是接口ILocation的其他方法。这有效:

public Location getStartLocation()
{
    return start;
}

......即使"要求"方法将是"公共 ILocation getStartLocation"。任何人都可以解释为什么这样,以及任何帮助使代码不那么尴尬?我希望能够将位置用作参数,而不是ILocation。

2 个答案:

答案 0 :(得分:1)

问题是接口需要一个接受任何作为ILocation子类型的参数的方法,而不仅仅是特定类型Location的对象。如果您的另一个具体类型PositionILocation的子类型,那么实现该接口将要求您接受Position对象以及Location对象。 / p>

请注意,在使用强制转换的解决方法中,如果您碰巧传递了ClassCastException而不是Position对象,则会在运行时获得Location

作为一个设计问题,要解决这个问题,您可以将界面定义为通用:

interface <T extends ILocation> TheInterface {
    void setGoalLocation(T loc);
}

然后你的具体类可以绑定泛型参数:

public class MyClass implements TheInterface<Location> {
    public void setGoalLocation(Location loc) {
        . . .
    }
}

至于返回类型,因为任何Location对象都是ILocation,因此当您返回Location时,您将返回ILocation

答案 1 :(得分:0)

Java支持协变返回类型,其中子类(或接口实现)中的方法的返回类型可以返回声明类型的子类(或实现)。所以一般情况下,允许以下内容

public class A {}

public class B extends A {}

public class C {
    A getSomething();
}

public class D extends C {
    B getSomething();
}

如果接口有一个采用接口类型的方法,则不能使用不同的签名覆盖它。

public interface I {
    void setSomething(ISomething somethingInterface);
}

你做不到

public class Something implements ISomething {}

public class MyI implements I {
    void setSomething(Something somethingInterface);
}