Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.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,以下是类声明: public interface IPoint<N extends Number> { ... } public abstract class PointP<N extends Number> implements IPoint<N> { ... } public class Pointf extends PointP<Float> { ... } public interface ISegment<T extends

以下是类声明:

public interface IPoint<N extends Number> {
...
}

public abstract class PointP<N extends Number> implements IPoint<N> {
...
}

public class Pointf extends PointP<Float> {
...
}

public interface ISegment<T extends Number, P extends IPoint<T>> {
...
}

public abstract class SegmentP<N extends Number, P extends IPoint<N>> implements ISegment<N, P> {
...
}

public class Segmentf extends SegmentP<Float, Pointf> {
...
}

public abstract class LinesPIterator<N extends Number, S extends ISegment<N, IPoint<N>>> implements Iterable<S>, Iterator<S> {
...
}

public class LinesfIterator extends LinesPIterator<Float, Segmentf> {
...
}
公共接口IPoint{
...
}
公共抽象类PointP实现了IPoint{
...
}
公共类Pointf扩展了PointP{
...
}
公共接口段{
...
}
公共抽象类SegmentP实现ISegment{
...
}
公共类Segmentf扩展了SegmentP{
...
}
公共抽象类LineSpiderator实现Iterable、迭代器{
...
}
公共类LinesIterator扩展了LinesIterator{
...
}
编译器拒绝行迭代器类的泛型声明中的分段F类型,并显示错误消息:

Bound mismatch: The type Segmentf is not a valid substitute for the bounded parameter <S extends ISegment<N,IPoint<N>>> of the type LinesPIterator<N,S>
绑定不匹配:类型Segmentf不是类型LinesPetrator的绑定参数的有效替代品
然而,对我来说,一切似乎都是正确的。在我看来,LinesfIterator类的声明与Segmentf类具有相同的层次架构,该类编译没有问题


这种做法有解决办法吗?

如前所述,您的层次结构似乎过于复杂,应该简化。例如,我在层次结构中看不到任何意义

如果要解决问题,必须允许子类型
?在
行运算符
类中扩展IPoint
,以便:

public abstract class LinesPIterator<N extends Number, S extends ISegment<N, ? extends IPoint<N>>> 
    implements Iterable<S>, Iterator<S> 
{
    // ...
}

如前所述,您的层级结构似乎过于复杂,应予以简化。例如,我在层次结构中看不到任何意义

如果要解决问题,必须允许子类型
?在
行运算符
类中扩展IPoint
,以便:

public abstract class LinesPIterator<N extends Number, S extends ISegment<N, ? extends IPoint<N>>> 
    implements Iterable<S>, Iterator<S> 
{
    // ...
}

这句关于使用匿名类而不是直接使用的评论确实引起了我的注意,因为直觉上,当我可以避免使用匿名类时,我会这样做。一方面是因为它是一个额外的实例化,另一方面是因为它在调试时更难识别(当它们在同一个类中有多个时)。 我不明白为什么我更喜欢在这种情况下使用匿名类。 也许以我的课程为例,解释会更容易

for(Segmentf segment : new LinesfIterator(cube.getPoints(), cube.getIndices())) {
    System.out.println(segment);
}

public abstract class LinesPIterator<N extends Number, S extends ISegment<N, ? extends IPoint<N>>> implements Iterable<S>, Iterator<S> {
    private N[][] points;
    private int[] indices;
    private int count;

    public LinesPIterator(N[][] points, int[] indices) {
        super();
        this.points = points;
        this.indices = indices;
    }

    protected abstract S instanciateIteration(final N[] pointDeb, final N[] pointFin);

    @Override
    public Iterator<S> iterator() {
        return this;
    }

    @Override
    public boolean hasNext() {
        return count < (indices.length - 1);
    }

    @Override
    public S next() {
        return instanciateIteration(points[indices[count++]], points[indices[count++]]);
    }
}

public class LinesfIterator extends LinesPIterator<Float, Segmentf> {

    public LinesfIterator(Float[][] points, int[] indices) {
        super(points, indices);
    }

    @Override
    protected Segmentf instanciateIteration(Float[] point1, Float[] point2) {
        return new Segmentf(point1, point2);
    } 
}
for(Segmentf segment:newlinesfiterator(cube.getPoints(),cube.getindex()){
系统输出打印项次(段);
}
公共抽象类LineSpiderator实现Iterable、迭代器{
私人N[][]点;
私人指数;
私人整数计数;
公共线条运算符(N[][]点,int[]索引){
超级();
这个点=点;
该指数=指数;
}
受保护的摘要S实例迭代(最终N[]点deb,最终N[]点fin);
@凌驾
公共迭代器迭代器(){
归还这个;
}
@凌驾
公共布尔hasNext(){
返回计数<(索引长度-1);
}
@凌驾
公共服务的下一步(){
返回实例迭代(点[索引[计数+]),点[索引[计数+]);
}
}
公共类LinesIterator扩展了LinesIterator{
公共行迭代器(浮点[][]点,整数[]索引){
超级(点数、指数);
}
@凌驾
受保护的段F实例迭代(浮点[]点1,浮点[]点2){
返回新的段F(点1、点2);
} 
}

这句关于使用匿名类而不是直接使用的评论确实引起了我的注意,因为直觉上,当我可以避免使用匿名类时,我会这样做。一方面是因为它是一个额外的实例化,另一方面是因为它在调试时更难识别(当它们在同一个类中有多个时)。 我不明白为什么我更喜欢在这种情况下使用匿名类。 也许以我的课程为例,解释会更容易

for(Segmentf segment : new LinesfIterator(cube.getPoints(), cube.getIndices())) {
    System.out.println(segment);
}

public abstract class LinesPIterator<N extends Number, S extends ISegment<N, ? extends IPoint<N>>> implements Iterable<S>, Iterator<S> {
    private N[][] points;
    private int[] indices;
    private int count;

    public LinesPIterator(N[][] points, int[] indices) {
        super();
        this.points = points;
        this.indices = indices;
    }

    protected abstract S instanciateIteration(final N[] pointDeb, final N[] pointFin);

    @Override
    public Iterator<S> iterator() {
        return this;
    }

    @Override
    public boolean hasNext() {
        return count < (indices.length - 1);
    }

    @Override
    public S next() {
        return instanciateIteration(points[indices[count++]], points[indices[count++]]);
    }
}

public class LinesfIterator extends LinesPIterator<Float, Segmentf> {

    public LinesfIterator(Float[][] points, int[] indices) {
        super(points, indices);
    }

    @Override
    protected Segmentf instanciateIteration(Float[] point1, Float[] point2) {
        return new Segmentf(point1, point2);
    } 
}
for(Segmentf segment:newlinesfiterator(cube.getPoints(),cube.getindex()){
系统输出打印项次(段);
}
公共抽象类LineSpiderator实现Iterable、迭代器{
私人N[][]点;
私人指数;
私人整数计数;
公共线条运算符(N[][]点,int[]索引){
超级();
这个点=点;
该指数=指数;
}
受保护的摘要S实例迭代(最终N[]点deb,最终N[]点fin);
@凌驾
公共迭代器迭代器(){
归还这个;
}
@凌驾
公共布尔hasNext(){
返回计数<(索引长度-1);
}
@凌驾
公共服务的下一步(){
返回实例迭代(点[索引[计数+]),点[索引[计数+]);
}
}
公共类LinesIterator扩展了LinesIterator{
公共行迭代器(浮点[][]点,整数[]索引){
超级(点数、指数);
}
@凌驾
受保护的段F实例迭代(浮点[]点1,浮点[]点2){
返回新的段F(点1、点2);
} 
}

您的继承层次结构看起来过于复杂,这是没有充分理由的。或者,换一种方式说@Kayaman的观点,我希望您试图解决的问题能够满足这种复杂程度。这样复杂的泛型可能是必要的,但如果您发现它们很难使用,则可能值得重新思考。比方说,我必须使用由数字类型组成的对象,这些类型必须能够根据需要进行浮点或双精度运算。我通常使用接口将对象传输到其他对象。抽象类用于子类共有的属性和实现,特别是用于子类强制实现的抽象方法。最后是具体类。我看不出我该如何简化这一点。你的继承层次结构看起来过于复杂,没有什么好的理由。或者,用另一种方式说@Kayaman的观点,我希望你试图解决的问题值得达到这种复杂程度。这种复杂的泛型可能是必要的,但也可能是必要的