我可以扩展 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 类型,例如 NameIterator
或 PlaceIterator
。
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;
我很沮丧,正在尝试向自定义迭代器添加方法。
对于我第二季度的作业 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 类型,例如 NameIterator
或 PlaceIterator
。
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;