简体   繁体   English

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

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

I'm frustrated, trying to add methods to a custom iterator. 我很沮丧,试图将方法添加到自定义迭代器中。

For an assignment in my second quarter Java class, we are supposed to implement, from scratch, a linked list. 对于第二节Java类中的作业,我们应该从头开始实现一个链表。 No problem: I have created an outer class to implement the linked list and a static private inner class to implement the individual nodes, to encapsulate them, hidden from any client program. 没问题:我创建了一个外部类来实现链接列表,并创建了一个静态私有内部类来实现各个节点,以封装它们,将其隐藏在任何客户端程序中。

The nodes in this linked list are to have two distinct next fields (one for names and another for places). 此链接列表中的节点将具有两个不同的下一个字段(一个用于名称,另一个用于位置)。 Following one of the next fields will take me through all the nodes by one path; 跟随下一个字段之一,将带我通过一条路径浏览所有节点。 following the other next field will take me another route. 跟随另一个下一个领域将带我另一条路线。 (Think two distinct alphabetical orders, depending on name or on place.) No problem: to iterate through the nodes, following the names or following the places, I created two custom iterators. (根据名称或位置来考虑两个不同的字母顺序。)没问题:要遍历节点,遵循名称或遵循位置,我创建了两个自定义迭代器。 One abstract class implements Iterator< Node > and common code, and two inner classes implement the custom code for each iterator through either the nextName field or the nextPlace field. 一个抽象类实现Iterator< Node >和通用代码,两个内部类通过nextName字段或nextPlace字段为每个迭代器实现自定义代码。

The next() and hasNext() methods work beautifully, giving customized results depending on whether I've instantiated a name or a place iterator. next()hasNext()方法可以很好地工作,根据我实例化名称还是位置迭代器来提供自定义结果。

These nodes also contain data I want to print to the console and save in a file. 这些节点还包含我要打印到控制台并保存在文件中的数据。 The nodes were deliberately encapsulated inside the list class to protect them from rogue use by a client program. 这些节点被故意封装在list类中,以防止它们被客户端程序恶意使用。 I thought to extend my iterators by adding accessor methods, such as getName() and getPlace() methods. 我想通过添加访问器方法(例如getName()getPlace()方法getName()来扩展迭代器。 It's why I took the extra step of creating an abstract class, rather than having my custom iterators directly implement Iterator . 这就是为什么我采取额外的步骤来创建抽象类,而不是让我的自定义迭代器直接实现Iterator

But it's not working. 但这不起作用。 I get "cannot find symbol" when I call itr.getName() from the client. 当我从客户端调用itr.getName()时,我得到“找不到符号”。 The closest answer I've seen is here but I still get "cannot find symbol." 我看到的最接近的答案是在这里,但我仍然得到“找不到符号”。

Here's a synopsis of my code: 这是我的代码的摘要:

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;

        // ...
    }
}

I want the client code to be able to run: 我希望客户端代码能够运行:

    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
    }

Sorry for the long question. 对不起,很长的问题。 It's my first here, and I'm still figuring out what exactly my problem even is. 这是我第一次来,我仍然在弄清楚我的问题到底是什么。

nameIterator() must return NameIterator instead of Iterator<Node> . nameIterator()必须返回NameIterator而不是Iterator<Node>

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

And the client code must use NameIterator instead of Iterator<Node> . 并且客户端代码必须使用NameIterator而不是Iterator<Node>

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

After reading discussion in comments, I suggest you to use IDE that can help you to resolve compile errors, like Intellij IDEA , for example. 阅读评论中的讨论后,建议您使用可以帮助您解决编译错误的IDE,例如Intellij IDEA

Short review of your problems: 简短回顾您的问题:

As was said, your List methods that return custom iterators, must have a concrete return type like NameIterator or PlaceIterator . 如前所述,您的返回自定义迭代器的List方法必须具有具体的返回类型,例如NameIteratorPlaceIterator

I applied both fixes -- declaring itr as a NameIterator in the client code; 我应用了两个修复程序-在客户端代码中将itr声明为NameIterator; returning a NameIterator when nameIterator() is called. 调用nameIterator()时返回一个NameIterator。 Sigh. 叹。 Now "cannot find symbol" has moved to point to the NameIterator itr declaration. 现在,“找不到符号”已移至指向NameIterator itr声明。

It seems, that compiler does not see your inner NameIterator class. 看来,编译器看不到您的内部NameIterator类。 To use inner class from outside the outer class, you should specify outer class name as well: 要从外部类外部使用内部类,还应指定外部类名称:

MyList.NameIterator itr = myList.nameIterator();

Or import this class: 或导入此类:

import your.package.MyList.NameIterator;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM