使用Java中的泛型保证协变返回类型 [英] Guarantee covariant return type with generics in Java
问题描述
我有一个名为 Point
的类,其方法是 neighbors()
,它返回一个数组of Point
s:
I have a class called Point
, with a method neighbors()
that returns an array of Point
s:
public class Point {
public Point[] neighbors() { /* implementation not shown */ }
}
我有一个 Point
的子类,名为 SpecialPoint
,它会覆盖邻居()
返回 SpecialPoint
的数组,而不是 Point
s。我认为这称为协变返回类型。
I have a subclass of Point
, called SpecialPoint
that overrides neighbors()
to return an array of SpecialPoint
s instead of Point
s. I think this is called covariant return types.
public class SpecialPoint extends Point {
public SpecialPoint[] neighbors() { /* implementation not shown */ }
}
在另一个类中,我想使用泛型
In a separate class, I want to make use of Point
and SpecialPoint
with generics
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 []
。
This will not compile, because the compiler can only guarantee that P
is some subclass of Point
, but there is no guarantee that every subclass of Point
will override neighbors()
to return an array of itself as I happen to have done with SpecialPoint
, so Java only knows that P#neighbors()
returns Point[]
, not P[]
.
我如何保证每个子类重写 neighbors()
有一个协变返回类型,所以我可以用泛型?
How do I guarantee that each subclass overrides neighbors()
with a covariant return type so I can use it with generics?
推荐答案
您可以使用界面:
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();
/* ... */
}
如果你仍然需要在实现之间分解代码,那么最好使用抽象类:
If you still need to factorize code between the implementations, then better use an abstract class:
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> { /* ... */ }
这篇关于使用Java中的泛型保证协变返回类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!