2016-02-04 67 views
2

我想弄清楚静态嵌套类与内部类(非静态嵌套类)的实现中的细微差别。例如,在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; 
     } 
    } 
    ... 

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

+1

这不是必须的,但它更好**封装**。 –

+1

祝贺您获得正确的术语。 – EJP

回答

1

嵌套类有点奇怪。在第一个例子中,我们有一个静态嵌套类。它必须通过OuterClass的“父”实例访问variable,因为它没有包含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); 
     } 
    } 
} 
+0

'静态内部'是一个[矛盾](http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.3)。 OP有这个很正确。不要混淆这个问题。 – EJP

+0

它仍然在外部类块的**内部定义,不是吗? – CodeBlind

+1

阅读链接或OP的括号。你正在寻找的词是'嵌套'。 – EJP