1. 程式人生 > >輕鬆掌握JAVA巢狀類

輕鬆掌握JAVA巢狀類

定義

巢狀類,顧名思義,就是定義在一個類內部的類。


分類

定義在類的內部,就與類的成員(即屬性和方法)“平起平坐”,而類的成員可分為靜態成員和非靜態成員,之於巢狀類,也是有如此相似的特點——巢狀類分為靜態巢狀類和非靜態巢狀類,非靜態巢狀類又名內部類,而內部類中又有兩種很特殊的內部類,即區域性內部類和匿名內部類,因此,巢狀類的分類如下圖所示:

巢狀類的分類


共性

巢狀類與普通類既有共同點也有很多需要額外注意的地方,因此,本文為了能夠教全面地點到這些異同,就先說說巢狀類的如下共性:

  1. 巢狀類可以擁有哪些型別的成員?
    • 靜態巢狀類:可以擁有靜態成員和非靜態成員
    • 非靜態巢狀類:只能擁有非靜態成員
  2. 巢狀類能使用哪些修飾詞?
    • 巢狀類同樣可用abstract、final來修飾
    • 靜態巢狀類和(普通)內部類可用public、protected、<預設>、private來修飾,從而控制它的訪問許可權
      public、protected、<預設>、private用來修飾類的成員,而巢狀類很像類的“第三種”成員,從這個角度看,就很容易理解這點。

詳解

下面分別從定義巢狀類、建立巢狀類物件以及巢狀類和外部類的關係這三方面異議詳解如上四種巢狀類。

靜態巢狀類

  • 1.定義

    靜態巢狀類在外部類定義成員的地方定義,形如:
class OuterClass {
    ……
    static class StaticNestedClass{
        ……
    }
    ……
}
  • 2.建立物件
    前文已經提到,靜態巢狀類類似於靜態屬性和靜態方法,因此,可以像它們一樣直接通過類名來使用
    (PS:關於這點,通過與後邊介紹的內部類的使用就能有更深切的領會)
    靜態巢狀類物件的建立形如:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass
();
  • 3.與外部類的關係
    靜態巢狀類只能訪問外部類的靜態成員(包括靜態屬性和靜態方法)
    想想這是為什麼?如上所示,通過類名就可以直接建立靜態巢狀類的物件,他與外部類的例項物件沒有關係——靜態巢狀類很“獨立”,而非靜態成員只有在建立了物件後才能通過物件名來訪問。靜態巢狀類在建立物件時,它的外部類可能沒有建立物件,因此,就沒有可供訪問的非靜態屬性。
    這就可以看出靜巢狀類與它的外部類的關係比較弱。

內部類

  • 1.定義
    內部類和靜態巢狀類一樣,在外部類定義成員的地方定義,形如:
class OuterClass{
    ……
    class InnerClass{
        ……
    }
    ……
}

與靜態巢狀類相比,它不需要用static關鍵字來修飾。

  • 2.建立物件
    內部類類似於普通的屬性和方法,因此,在建立它的物件時,首先要建立它的外部類的物件,然後再用該物件建立內部類的物件,形如:
OuterClass outerObject = new OuterObject();
OuterClass.InnerClass innerObject = outerObject.new InnerClass();

要注意outerObject.new這部分的寫法。
由此可見,與前面講到的靜態巢狀類物件的建立有很明顯的區別。

  • 3.與外部類的聯絡
    內部類可以直接訪問外部類的所有成員(包括靜態和非靜態的屬性和方法)
    想想這是為什麼?因為在建立內部類的物件時,首先要建立外部類的物件,因此,有可以被訪問的外部類的屬性和方法。

區域性內部類

  • 1.定義
    區域性內部類是定義在方法體中的內部類。定義區域性內部類的形如:
class OuterClss{
    ……
    public void method(){
    ……
        class LocalInnerClass{
            ……
        }
    ……  
    }
    ……
}
  • 2.使用範例
    注意,區域性內部類很像區域性變數,不能從方法外訪問,因而,它的使用形如:
public class Example {

    public static void main(String[] args) {
        say();
    }

    private static void say() {
        class People {
            private String name = "Jully";
            private int age = 18;
            protected void introduce() {
                System.out.println("大家好,我是" + name + ",我今年" + age + "歲");
            }
        }

        People people = new People();
        people.introduce();
    }
}

程式執行結果如下圖:
這裡寫圖片描述

  • 3. 注意點
    區域性內部類只能訪問方法的final型別的區域性變數。

匿名內部類

匿名內部類的定義和使用常如如下形式:

public class OuterClass {
    ……
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("這是一個實現了Runnable介面的匿名內部類中的Run方法");
        }
    });
    ……
}

匿名內部類可以用來繼承一個類或實現一個介面,但不能同時實現這兩種功能,上面的例子是用一個類實現了Runnable介面,同時也建立了一個匿名物件,但這個類是匿名的。

博主水平有限,加之時間倉促,錯漏難免,望不吝賜教!