我有一个名为的类Point,其方法neighbors()返回一个Points 数组:
public class Point {
public Point[] neighbors() { /* implementation not shown */ }
}
Run Code Online (Sandbox Code Playgroud)
我有一个子类Point,称为SpecialPoint覆盖neighbors()返回一个SpecialPoints而不是Points 的数组.我认为这称为协变返回类型.
public class SpecialPoint extends Point {
public SpecialPoint[] neighbors() { /* implementation not shown */ }
}
Run Code Online (Sandbox Code Playgroud)
在一个单独的课程中,我想利用Point和SpecialPoint使用泛型
public <P extends Point> P doStuff(P point) {
P[] neighbors = point.neighbors();
// more stuff here including return
}
Run Code Online (Sandbox Code Playgroud)
这不会编译,因为编译器只能保证它P是某个子类Point,但不能保证每个子类Point都会覆盖neighbors()以返回一个自己的数组,因为我碰巧已经完成了SpecialPoint,所以Java只知道P#neighbors()返回Point[],而不是P[].
我如何保证每个子类都覆盖neighbors()一个协变返回类型,以便我可以使用泛型?
sp0*_*00m 14
您可以使用界面:
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() { /* ... */ }
}
Run Code Online (Sandbox Code Playgroud)
然后:
public <P extends Point<P>> P doStuff(P point) {
P[] neighbors = point.neighbors();
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
如果您仍然需要在实现之间分解代码,那么最好使用抽象类:
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> { /* ... */ }
Run Code Online (Sandbox Code Playgroud)