Java Inner Class

C# Partial 關鍵字

轉貼至:http://pvencs.blogspot.tw/2011/06/java-inner-class.html

inner class的作用並不只是隱藏名稱或程式碼
他最大的效果是能有效及完整的達到"多重繼承"-實際上繼承多個non-interface

inner class的個用途是當建立一個inner class時
inner class可以存取外圍物件的所有元素而無需添加任何飾詞,如下範例:


    boolean end();
    Object current();
    void next();
} 

public class Sequence {
    private Object[] items;
    private int next = 0;
    public Sequence(int size) {
        items = new Object[size];
    }
    public void add(Object x) {
        if (next < items.length) items[next++] = x;
    }
    private class SequenceSelector implements Selector {
        private int i = 0;
        public boolean end() {
            return i == items.length;
        }
        public Object current() {
            return items[i];
        }
        public void next() {
            if (i < items.length) i++;
        }
    }
    public Selector selector() {
        return new SequenceSelector();
    }
    public static void main(String[] args) {
        Sequence sequence = new Sequence(10);
        for (int i = 0; i < 10; i++)
        sequence.add(Integer.toString(i));
        Selector selector = sequence.selector();
        while (!selector.end()) {
            System.out.print(selector.current() + " ");
            selector.next();
        }
    }
}
/* Output:
0 1 2 3 4 5 6 7 8 9
*/ 

範例的inner class的SequenceSelector可以存取其外部的Sequence的類別成員
不論inner class內放置的層次有多深
所有的outer classes的成員,即使是private修飾也都可以被他存取

inner class必須記錄一個reference指向enclosing class(外圍類別)
當取用外部成員時,編譯器會自動用那個隱藏的reference取得
也因為inner class物件產生時必須要關聯至其enclosing class的某個物件
建構inner class物件的同時必須要有enclosing class的物件

inner class可以寫在程式的任意位置
這不是說他們只會在執行那個段落時產生
他們一樣會跟其他class一起被編譯出來,只是在該段落以外無法被使用

假如不需要inner class物件和enclosing class物件之間的連結關係
可以將inner class宣告為static,而這種class被稱為nested class
nested class在生成物件時不需要外圍class的物件,也無法存取外圍class的非靜態物件
一般的inner class不能擁有static data、static fields或nested class,但nested class都可以有

一般而言,interface內不能加入任何程式碼,但nested class卻可以是interface的一部分
任何加到interface的class會自動成為public和static
甚至可以在inner class中時做外圍的interface
如果想寫出讓某interface的不同實作都可以共用的程式碼時可以這麼做,如下:


    String getAnswer();
    class Test implements ClassInInterface {
        public String getAnswer() {
            return "good day";
        }
    }
} 

System.out.println(new ClassInInterface.Test().getAnswer()); 

繼承inner class則必須注意要先建立外圍類別
指向outer class的reference也必須在建構式由我們建立,如下:


  class Inner {}
} 

public class InheritInner extends WithInner.Inner {
  //! InheritInner() {} // Won't compile
  InheritInner(WithInner wi) {
    wi.super();
  }
  public static void main(String[] args) {
    WithInner wi = new WithInner();
    InheritInner ii = new InheritInner(wi);
  }
}