使用Java中的generics保证协变返回类型
我有一个名为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 */ } }
在一个单独的类中,我想使用generics和Point
和SpecialPoint
public P doStuff(P point) { P[] neighbors = point.neighbors(); // more stuff here including return }
这不会编译,因为编译器只能保证P
是Point
某个子类,但是不能保证Point
每个子类都会覆盖neighbors()
以返回自己的数组,因为我碰巧使用了SpecialPoint
,所以Java只知道P#neighbors()
返回Point[]
,而不是P[]
。
我如何保证每个子类用协变返回类型覆盖neighbors()
,以便我可以将它与generics一起使用?
您可以使用界面:
public interface Point> { P[] neighbors(); } public class SimplePoint implements Point { @Override public SimplePoint[] neighbors() { /* ... */ } } public class SpecialPoint implements Point { @Override public SpecialPoint[] neighbors() { /* ... */ } }
然后:
public > P doStuff(P point) { P[] neighbors = point.neighbors(); /* ... */ }
如果您仍然需要在实现之间分解代码,那么最好使用抽象类:
public abstract class Point> { public abstract P[] neighbors(); public void commonMethod() { /* ... */ } } public class SimplePoint extends Point { /* ... */ } public class SpecialPoint extends Point { /* ... */ }
可能是一个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]; } }