Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中带有泛型的保证协变返回类型_Java_Generics - Fatal编程技术网

Java中带有泛型的保证协变返回类型

Java中带有泛型的保证协变返回类型,java,generics,Java,Generics,我有一个名为Point的类,它有一个方法neights(),该方法返回一个Points的数组: 公共类点{ 公共点[]邻居(){/*未显示实现*/} } 我有一个子类Point,名为SpecialPoint,它覆盖neights(),返回一个SpecialPoints数组,而不是Points数组。我认为这叫做协变返回类型 公共类特殊点扩展点{ 公共特殊点[]邻居(){/*未显示实现*/} } 在一个单独的类中,我想将Point和SpecialPoint与泛型一起使用 publicP doSt

我有一个名为
Point
的类,它有一个方法
neights()
,该方法返回一个
Point
s的数组:

公共类点{
公共点[]邻居(){/*未显示实现*/}
}
我有一个子类
Point
,名为
SpecialPoint
,它覆盖
neights()
,返回一个
SpecialPoint
s数组,而不是
Point
s数组。我认为这叫做协变返回类型

公共类特殊点扩展点{
公共特殊点[]邻居(){/*未显示实现*/}
}
在一个单独的类中,我想将
Point
SpecialPoint
与泛型一起使用

publicP doStuff(P点){
P[]邻居=点。邻居();
//这里有更多的东西,包括退货
}
这不会编译,因为编译器只能保证
p
Point
的某个子类,但不能保证
Point
的每个子类都会覆盖
邻居()
以返回自身的数组,就像我碰巧对
SpecialPoint
所做的那样,因此Java只知道
P#neighbories()
返回
Point[]
,而不是
P[]


如何保证每个子类使用协变返回类型重写邻域(),以便我可以将其用于泛型?

您可以使用一个接口:

公共接口点{
P[]邻居();
}
公共类SimplePoint实现了点{
@凌驾
公共SimplePoint[]邻居(){/*…*/}
}
公共类SpecialPoint实现了该点{
@凌驾
公共特殊点[]邻居(){/*…*/}
}
然后:

publicP doStuff(P点){
P[]邻居=点。邻居();
/* ... */
}

如果仍然需要在实现之间分解代码,那么最好使用抽象类:

公共抽象类点{
公共摘要P[]邻居();
public void commonMethod(){/*…*/}
}
公共类SimplePoint扩展点{/*…*/}
公共类SpecialPoint扩展点{/*…*/}

可能有一个
接口点
可以解决您的问题:

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];
    }
}

P可以是一个界面吗?哇,我从来没有想过这个。我唯一的问题是,出于其他原因,我仍然希望
SpecialPoint
继承自
SimplePoint
。这样它就不会编译,因为
P
中的
P
必须扩展
也属于
P
,但是
SepcialPoint
扩展
。不管怎么说?@JJW5432还有其他原因吗?如果目的是分解代码,那么一个额外的抽象类可以满足您的需要。是的,大多数其他方法在类之间是相同的,这就是我想要继承的原因。因此存在AbstractPoint,SimplePoint和SpecialPoint都继承自它并实现Point?@JJW5432好吧,最好是使用抽象类而不是接口,请参见我的编辑。
Point
声明中的绑定未使用,对于OP来说不必要<代码>公共接口点已足够。