说我正在创建一个实现接口的类,并且有这样的代码:
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。
答案 0 :(得分:1)
问题是接口需要一个接受任何作为ILocation
子类型的参数的方法,而不仅仅是特定类型Location
的对象。如果您的另一个具体类型Position
是ILocation
的子类型,那么实现该接口将要求您接受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);
}