繁体   English   中英

使用Java中的泛型保证协变返回类型

[英]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 */ }
}

在一个单独的类中,我想使用泛型和PointSpecialPoint

public <P extends Point> P doStuff(P point) {
    P[] neighbors = point.neighbors();
    // more stuff here including return
}

这不会编译,因为编译器只能保证PPoint某个子类,但是不能保证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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM