混合内部类和静态嵌套类

时间:2016-02-04 23:28:28

标签: java

我试图找出静态嵌套类与内部类(非静态嵌套类)的实现方面的细微差别。例如,在http://algs4.cs.princeton.edu/code/edu/princeton/cs/algs4/Queue.java.html上,您可以找到以下代码:

public class Queue<Item> implements Iterable<Item> {
    private Node<Item> first;    // beginning of queue
    private Node<Item> last;     // end of queue
    private int N;               // number of elements on queue

    // helper linked list class
    private static class Node<Item> {
        private Item item;
        private Node<Item> next;
    }

    ...
    /**
     * Returns an iterator that iterates over the items in this queue in FIFO order.
     *
     * @return an iterator that iterates over the items in this queue in FIFO order
     */
    public Iterator<Item> iterator()  {
        return new ListIterator<Item>(first);  //why parameter needed?
    }

    // an iterator, doesn't implement remove() since it's optional
    private class ListIterator<Item> implements Iterator<Item> {
        private Node<Item> current;  //why not current = first?

        public ListIterator(Node<Item> first) {
            current = first;
        }

        public boolean hasNext()  { return current != null;                     }
        public void remove()      { throw new UnsupportedOperationException();  }

        public Item next() {
            if (!hasNext()) throw new NoSuchElementException();
            Item item = current.item;
            current = current.next; 
            return item;
        }
    }
    ...

我想知道为什么你必须通过first的构造函数传递变量ListIterator?为什么我不能在声明时使用private Node<Item> current = first;。我知道如果我使用Node的内部类,我可以直接将first分配给current(就像在http://algs4.cs.princeton.edu/13stacks/LinkedQueue.java.html中一样)。

1 个答案:

答案 0 :(得分:1)

嵌套类有点奇怪。在第一个例子中,我们有一个静态嵌套类。它必须通过父母&#34;访问variableOuterClass的实例,因为它没有封闭的OuterClass实例。当我们静态地定义嵌套类时,它几乎就像它们在它们自己的单独文件中定义一样。唯一的区别是静态嵌套类可以访问OuterClass的私有成员,而如果它们是在自己的单独文件中定义的话,它们就不会。

public class OuterClass{
    private Object variable = "variable";

    private static class StaticNestedClass{
        private OuterClass parent;

        private StaticNestedClass(OuterClass p){ parent = p; }

        private void method(){
            //This line compiles:
            System.out.println("variable = "+parent.variable);

            //This won't - there's no OuterClass enclosing instance:
            //System.out.println("variable = "+OuterClass.this.variable);

            //This one won't either, for the same reason:
            //System.out.println("variable = "+variable);
        }
    }
}

让我们稍微改变一下。现在我们的嵌套类不是静态的,这意味着它包含在OuterClass的实例中。它仍然可以访问OuterClass的私有成员,但我们不需要将OuterClass的实例存储到其构造函数中以用于存储目的,因为它隐式地引用了OuterClass包含它的实例。

public class OuterClass{
    private Object variable = "variable";

    private class InnerClass{
        private void method(){
            //This line compiles:
            System.out.println("variable = "+variable);

            //So does this one - both lines refer to the same 
            //enclosing instance of OuterClass:
            System.out.println("variable = "+OuterClass.this.variable);
        }
    }
}