Java 重写迭代器类型

Java 重写迭代器类型,java,iterator,Java,Iterator,我有两个父类和两个子类。我对迭代器方法的返回类型有问题,它总是父类类型,子类不能重写它 请考虑以下代码: 公共类属性{} 公共类属性实现了Iterable{ 受保护的ArrayList attrs=新的ArrayList(); 公共迭代器迭代器(){ 返回这个.attrs.iterator(); } } // ------- 公共类Attr扩展属性{} 公共类属性扩展属性{} // ------- for(Attr Attr:attrs){ //错误!attrs.iterator()返回的属性

我有两个父类和两个子类。我对迭代器方法的返回类型有问题,它总是父类类型,子类不能重写它

请考虑以下代码:

公共类属性{}
公共类属性实现了Iterable{
受保护的ArrayList attrs=新的ArrayList();
公共迭代器迭代器(){
返回这个.attrs.iterator();
}
}
// -------
公共类Attr扩展属性{}
公共类属性扩展属性{}
// -------
for(Attr Attr:attrs){
//错误!attrs.iterator()返回的属性不是Attr
}
for(属性:attrs){
Attr Attr=(Attr)属性;
//工作
}
是否可以重写迭代器返回类型?

重写的方法必须与新方法兼容。 因此,以下覆盖是可以接受的:

public class Baa{
     .....
     public Baa returnSomething{
         return this;
     }
}


public class Foo extends Baa{
     .....
     @Override
     public Foo returnSomething{
         return this;
     }
}
即使你把这个物体看成是一个baa,所有的东西都是有效的

public static void main(String[] args){
    Baa test=new Foo(); //a Foo is a Baa so no problem

    Baa getSomething=test.returnSomething(); //returns a Foo, but a foo can be used as as a baa so no problem

}
这不适用于泛型 如果集合也发生同样的情况,这似乎很方便,但是您可以轻松地创建一个有运行时错误的示例

Collection<Intger> numbers=new ArrayList<Intger>();
Collection<Number> falseNumbers=(Collection<Number>)numbers; //pretend not an error
falseNumbers.add(new Double()); ////eeeek!
Collection number=new ArrayList();
集合编号=(集合)编号//假装没有错误
添加(新的双精度())////哎呀!
逆来顺受 使用泛型,如中所述,我们可以指示集合的最小和最大边界(基本上说,它们只能包含可以转换为特定类型的对象。通过使用泛型,我们可以创建不需要转换的迭代器:

public class Attribute {
    protected ArrayList<Attribute> attributes = new ArrayList<Attribute>();

    public Attribute(){
         //holding an array of yourself seems strange, but I am replicating the code in the question
         attributes.add(this);
    }

    public Iterator<? extends Attribute> iterator() {
        return this.attributes.iterator();
    }

    public static void main(String[] args){
        Attribute attribute=new Attribute();
        Iterator<? extends Attribute> it1=attribute.iterator();
        Attribute attributeInternat=it1.next();

        Attr attr=new Attr();
        Iterator<? extends Attr> it2=attr.iterator();
        Attr attrInternat=it2.next();
    }
}

public class Attr extends Attribute{
   protected ArrayList<Attr> attrs2 = new ArrayList<Attr>();
    public Attr(){
          //holding an array of yourself seems strange, but I am replicating the code in the question
          attrs2.add(this);
    }

    @Override
    public Iterator<? extends Attr> iterator() {
        return this.attrs2.iterator();
    }
}
公共类属性{
受保护的ArrayList属性=新建ArrayList();
公共属性(){
//持有你自己的数组似乎很奇怪,但我正在复制问题中的代码
属性。添加(此);
}

公共迭代器基本上将集合强制转换为集合是不起作用的,一开始似乎不合适,但如果可以,您可以向集合添加Child2或Parent,当然这将是runtimeexceptionsing(Attr)属性对编译器说的“我知道这可能会出错,我知道我在做什么,我接受我行为的后果”你可能希望看看我知道强制转换是个坏主意,我正在寻找某种方法来覆盖迭代器()并且改变它的行为。同样
所以最好的方法是使用迭代器对象而不是foreach。谢谢Richard@AHHP是的,出于某种原因,foreach似乎不喜欢这样,这本身就很有趣
public class Attribute {
    protected ArrayList<Attribute> attributes = new ArrayList<Attribute>();

    public Attribute(){
         //holding an array of yourself seems strange, but I am replicating the code in the question
         attributes.add(this);
    }

    public Iterator<? extends Attribute> iterator() {
        return this.attributes.iterator();
    }

    public static void main(String[] args){
        Attribute attribute=new Attribute();
        Iterator<? extends Attribute> it1=attribute.iterator();
        Attribute attributeInternat=it1.next();

        Attr attr=new Attr();
        Iterator<? extends Attr> it2=attr.iterator();
        Attr attrInternat=it2.next();
    }
}

public class Attr extends Attribute{
   protected ArrayList<Attr> attrs2 = new ArrayList<Attr>();
    public Attr(){
          //holding an array of yourself seems strange, but I am replicating the code in the question
          attrs2.add(this);
    }

    @Override
    public Iterator<? extends Attr> iterator() {
        return this.attrs2.iterator();
    }
}