我可以扩展 Iterator 以允许访问封装的内部 class 字段吗?

Can I extend Iterator to allow access to encapsulated inner class fields?

我很沮丧,正在尝试向自定义迭代器添加方法。

对于我第二季度的作业 Java class,我们应该从头开始实现一个链表。没问题:我创建了一个外部 class 来实现链表和一个静态私有内部 class 来实现各个节点,封装它们,对任何客户端程序隐藏。

此链表中的节点将有两个不同的下一个字段(一个用于名称,另一个用于位置)。按照下一个字段将带我通过一条路径通过所有节点;跟随另一个下一个字段将带我走另一条路。 (考虑两个不同的字母顺序,具体取决于名称或位置。)没问题:为了遍历节点,按照名称或按照位置,我创建了两个自定义迭代器。一个抽象 class 实现 Iterator< Node > 和通用代码,两个内部 class es 通过 nextName 字段或 nextPlace 字段为每个迭代器实现自定义代码。

next()hasNext() 方法工作得很好,根据我是实例化名称还是地点迭代器提供自定义结果。

这些节点还包含我要打印到控制台并保存在文件中的数据。这些节点被特意封装在列表 class 中,以保护它们免受客户端程序的恶意使用。我想通过添加访问器方法来扩展我的迭代器,例如 getName()getPlace() 方法。这就是为什么我采取了创建抽象 class 的额外步骤,而不是让我的自定义迭代器直接实现 Iterator.

但它不起作用。当我从客户端调用 itr.getName() 时,我得到 "cannot find symbol"。我见过的最接近的答案是 here 但我仍然得到 "cannot find symbol."

这是我的代码的概要:

import java.util.Iterator;

public class MyList implements Iterable {

    // ...

    public Iterator nameIterator() {
        return new NameIterator( this );
    }

    public Iterator placeIterator() {
        return new placeIterator( this );
    }

    public abstract class NodeIterator implements Iterator< Node > {

        public NodeIterator( MyList list ) { ... }

        public boolean hasNext() { ... } // this appears to work fine

        public String getName() { ... } // this can't be seen by the client

        public String getPlace() { ... } // this can't be seen by the client

    }

    private class NameIterator extends NodeIterator {

        public NameIterator( MyList list ) {
            super( list );
            ...
        }

        public Node next() { ... }

    }

    private class PlaceIterator extends NodeIterator { ... } // same as NameIterator with custom code

    private static class AttractionNode {
        public String  name;
        public String  place;

        public Node  nextName;
        public Node  nextPlace;

        // ...
    }
}

我希望客户端代码能够 运行:

    System.out.println( "\nBy names: " );
    Iterator itr = placesToGo.nameIterator();
    while( itr.hasNext() ) {
        itr.next();
        System.out.println( itr.getName() ); // gives me "cannot find symbol" error
        // System.out.println( itr.next() ); // works fine, alone
    }

抱歉这个问题太长了。这是我第一次来这里,我仍在弄清楚我的问题到底是什么。

nameIterator() 必须 return NameIterator 而不是 Iterator<Node>.

public NameIterator nameIterator() {
    return new NameIterator( this );
}

并且客户端代码必须使用NameIterator而不是Iterator<Node>

    System.out.println( "\nBy names: " );
    NameIterator itr = placesToGo.nameIterator();
    while( itr.hasNext() ) {
        itr.next();
        System.out.println( itr.getName() );
    } 

阅读评论中的讨论后,我建议您使用 IDE 可以帮助您解决编译错误,例如 Intellij IDEA

问题的简短回顾:

如前所述,return 自定义迭代器的 List 方法必须具有具体的 return 类型,例如 NameIteratorPlaceIterator

I applied both fixes -- declaring itr as a NameIterator in the client code; returning a NameIterator when nameIterator() is called. Sigh. Now "cannot find symbol" has moved to point to the NameIterator itr declaration.

看来,编译器没有看到你的内部 NameIterator class。要从外部 class 外部使用内部 class,您还应该指定外部 class 名称:

MyList.NameIterator itr = myList.nameIterator();

或导入此 class:

import your.package.MyList.NameIterator;