Java中带有泛型的保证协变返回类型
我有一个名为Java中带有泛型的保证协变返回类型,java,generics,Java,Generics,我有一个名为Point的类,它有一个方法neights(),该方法返回一个Points的数组: 公共类点{ 公共点[]邻居(){/*未显示实现*/} } 我有一个子类Point,名为SpecialPoint,它覆盖neights(),返回一个SpecialPoints数组,而不是Points数组。我认为这叫做协变返回类型 公共类特殊点扩展点{ 公共特殊点[]邻居(){/*未显示实现*/} } 在一个单独的类中,我想将Point和SpecialPoint与泛型一起使用 publicP doSt
Point
的类,它有一个方法neights()
,该方法返回一个Point
s的数组:
公共类点{
公共点[]邻居(){/*未显示实现*/}
}
我有一个子类Point
,名为SpecialPoint
,它覆盖neights()
,返回一个SpecialPoint
s数组,而不是Point
s数组。我认为这叫做协变返回类型
公共类特殊点扩展点{
公共特殊点[]邻居(){/*未显示实现*/}
}
在一个单独的类中,我想将Point
和SpecialPoint
与泛型一起使用
publicP doStuff(P点){
P[]邻居=点。邻居();
//这里有更多的东西,包括退货
}
这不会编译,因为编译器只能保证p
是Point
的某个子类,但不能保证Point
的每个子类都会覆盖邻居()
以返回自身的数组,就像我碰巧对SpecialPoint
所做的那样,因此Java只知道P#neighbories()
返回Point[]
,而不是P[]
如何保证每个子类使用协变返回类型重写邻域(),以便我可以将其用于泛型?您可以使用一个接口:
公共接口点{
P[]邻居();
}
公共类SimplePoint实现了点{
@凌驾
公共SimplePoint[]邻居(){/*…*/}
}
公共类SpecialPoint实现了该点{
@凌驾
公共特殊点[]邻居(){/*…*/}
}
然后:
publicP doStuff(P点){
P[]邻居=点。邻居();
/* ... */
}
如果仍然需要在实现之间分解代码,那么最好使用抽象类:
公共抽象类点{
公共摘要P[]邻居();
public void commonMethod(){/*…*/}
}
公共类SimplePoint扩展点{/*…*/}
公共类SpecialPoint扩展点{/*…*/}
可能有一个接口点
可以解决您的问题:
public class Test
{
public interface Point {
public Point[] neighbors();
}
public class SpecialPoint implements Point {
public SpecialPoint[] neighbors() { return null; }
}
public class SpecialPoint2 implements Point {
public SpecialPoint2[] neighbors() { return null; }
}
public Point doStuff(SpecialPoint point) {
Point[] neighbors = point.neighbors();
return neighbors[0];
}
public Point doStuff(SpecialPoint2 point) {
Point[] neighbors = point.neighbors();
return neighbors[0];
}
}
P可以是一个界面吗?哇,我从来没有想过这个。我唯一的问题是,出于其他原因,我仍然希望
SpecialPoint
继承自SimplePoint
。这样它就不会编译,因为P
中的P
必须扩展点
也属于P
,但是SepcialPoint
扩展点
。不管怎么说?@JJW5432还有其他原因吗?如果目的是分解代码,那么一个额外的抽象类可以满足您的需要。是的,大多数其他方法在类之间是相同的,这就是我想要继承的原因。因此存在AbstractPoint,SimplePoint和SpecialPoint都继承自它并实现Point?@JJW5432好吧,最好是使用抽象类而不是接口,请参见我的编辑。Point
声明中的绑定未使用,对于OP来说不必要<代码>公共接口点已足够。