[英]Guarantee covariant return type with generics in Java
我有一个名为Point
的类,有一个方法neighbors()
返回Point
的数组:
public class Point {
public Point[] neighbors() { /* implementation not shown */ }
}
我有一个Point
的子类,叫做SpecialPoint
,它会覆盖neighbors()
以返回一个SpecialPoint
而不是Point
的数组。 我认为这称为协变返回类型。
public class SpecialPoint extends Point {
public SpecialPoint[] neighbors() { /* implementation not shown */ }
}
在一个单独的类中,我想使用泛型和Point
和SpecialPoint
public <P extends Point> P doStuff(P point) {
P[] neighbors = point.neighbors();
// more stuff here including return
}
这不会编译,因为编译器只能保证P
是Point
某个子类,但是不能保证Point
每个子类都会覆盖neighbors()
以返回自己的数组,因为我碰巧使用了SpecialPoint
,所以Java只知道P#neighbors()
返回Point[]
,而不是P[]
。
我如何保证每个子类用协变返回类型覆盖neighbors()
,以便我可以将它与泛型一起使用?
您可以使用界面:
public interface Point<P extends Point<P>> {
P[] neighbors();
}
public class SimplePoint implements Point<SimplePoint> {
@Override
public SimplePoint[] neighbors() { /* ... */ }
}
public class SpecialPoint implements Point<SpecialPoint> {
@Override
public SpecialPoint[] neighbors() { /* ... */ }
}
然后:
public <P extends Point<P>> P doStuff(P point) {
P[] neighbors = point.neighbors();
/* ... */
}
如果您仍然需要在实现之间分解代码,那么最好使用抽象类:
public abstract class Point<P extends Point<P>> {
public abstract P[] neighbors();
public void commonMethod() { /* ... */ }
}
public class SimplePoint extends Point<SimplePoint> { /* ... */ }
public class SpecialPoint extends Point<SpecialPoint> { /* ... */ }
可能是一个interface Point
解决了你的问题:
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];
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.