1. 程式人生 > >Java -- 內部類(一)

Java -- 內部類(一)

能力 代碼 邏輯 play 無形中 匿名 成員內部類 產生 ret

什麽是內部類

將一個類的定義放在另一個類的定義內部,這就是內部類。
在Java中內部類主要分為成員內部類、局部內部類、匿名內部類、靜態內部類。
舉個栗子:

public class A { 
    public class B { 

    } 
};        

為什麽要用內部類

在《Think in java》中有這樣一句話:使用內部類最吸引人的原因是:每個內部類都能獨立地繼承一個(接口的)實現,所以無論外圍類是否已經繼承了某個(接口的)實現,對於內部類都沒有影響。
在我們程序設計中有時候會存在一些使用接口很難解決的問題,這個時候我們可以利用內部類提供的、可以繼承多個具體的或者抽象的類的能力來解決這些程序設計問題。可以這樣說,接口只是解決了部分問題,而內部類使得多重繼承的解決方案變得更加完整。

栗子:

public interface Father {}

public interface Mother {}

public class Son implements Father, Mother {}

public class Daughter implements Father{
    class Mother_ implements Mother{}
}

有什麽特性

  • 內部類可以用多個實例,每個實例都有自己的狀態信息,並且與其他外圍對象的信息相互獨立。
  • 在單個外圍類中,可以讓多個內部類以不同的方式實現同一個接口,或者繼承同一個類。
  • 創建內部類對象的時刻並不依賴於外圍類對象的創建。
  • 內部類並沒有令人迷惑的“is-a”關系,他就是一個獨立的實體。
  • 內部類提供了更好的封裝,除了該外圍類,其他類都不能訪問。

如何使用呢

當我們在創建一個內部類的時候,它無形中就與外圍類有了一種聯系,依賴於這種聯系,它可以無限制地訪問外圍類的元素。這是因為當我們在創建某個外圍類的內部類對象時,此時內部類對象必定會捕獲一個指向那個外圍類對象的引用,只要我們在訪問外圍類的成員時,就會用這個引用來選擇外圍類的成員.

@Getter
@Setter
public class OuterClass {
    private String name ;
    
private int age; public class InnerClass{ public InnerClass(){ name = "JackPotHan"; age = 23; }   public void display(){   System.out.println("name:" + getName() +" ;age:" +getAge());   }   } public static void main(String[] args) { OuterClass outerClass = new OuterClass(); OuterClass.InnerClass innerClass = outerClass.new InnerClass(); innerClass.display(); } } -------------- Output: name:JackPotHan ;age:23

註:在使用內部類時有些新手可能會遇到下面一個錯誤--"is not an enclosing class",因為按照正邏輯,應該是A.B ab = new A.B(); 但是翻看相關java代碼,會發現正確的用法是A a = new A(); A.B ab = a.new B(); 沒有靜態(static)的類中類不能使用外部類進行.操作,必須用實例來進行實例化類中類.

同時如果我們需要生成對外部類對象的引用,可以使用OuterClassName.this,這樣就能夠產生一個正確引用外部類的引用了。當然這點是在編譯期就知曉了,沒有任何運行時的成本。

栗子:

public class OuterClass {
    public void display(){
        System.out.println("OuterClass...");
    }

    public class InnerClass{
        public OuterClass getOuterClass(){
            return OuterClass.this;
        }
    }

    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        OuterClass.InnerClass innerClass = outerClass.new InnerClass();
      innerClass.getOuterClass().display();
    }
}
-------------
Output:
OuterClass...

到這裏了我們需要明確一點,內部類是個編譯時的概念,一旦編譯成功後,它就與外圍類屬於兩個完全不同的類(當然他們之間還是有聯系的)。對於一個名為OuterClass的外圍類和一個名為InnerClass的內部類,在編譯成功後,會出現這樣兩個class文件:OuterClass.class和OuterClass$InnerClass.class。

Java -- 內部類(一)