1. 程式人生 > 實用技巧 >2020年9月3日 內部類總結

2020年9月3日 內部類總結

## 7.10 內部類

1、內部類的概念

宣告在另外一個類裡面的類就是內部類。



2、內部類的4種形式

(1)靜態內部類

(2)非靜態成員內部類

(3)有名字的區域性內部類

(4)匿名內部類



### 7.10.1 匿名內部類

1、語法格式:

```java
//在匿名子類中呼叫父類的無參構造
new 父類(){
    內部類的成員列表
}

//在匿名子類中呼叫父類的有參構造
new 父類(實參列表){
    內部類的成員列表
}

//介面沒有構造器,那麼這裡表示匿名子類呼叫自己的無參構造,呼叫預設父類Object的無參構造
new 父介面名(){
    
}
```

2、匿名內部類、匿名物件的區別?

```java
System.out.println(
new Student("張三"));//匿名物件 Student stu = new Student("張三");//這個物件有名字,stu //既有匿名內部類,又是一個匿名的物件 new Object(){ public void test(){ ..... } }.test(); //這個匿名內部類的物件,使用obj這個名字引用它,既物件有名字,但是這個Object的子類沒有名字 Object obj = new Object(){ public void test(){ ..... } }; ``` 3、使用的形式 (1)示例程式碼:繼承式 ```java
abstract class Father{ public abstract void test(); } class Test{ public static void main(String[] args){ //用父類與匿名內部類的物件構成多型引用 Father f = new Father(){ public void test(){ System.out.println("用匿名內部類繼承了Father這個抽象類,重寫了test抽象方法") } }; f.test(); } } ``` (
2)示例程式碼:實現式 ```java interface Flyable{ void fly(); } class Test{ public static void main(String[] args){ //用父介面與匿名內部類的物件構成了多型引用 Flyable f = new Flyable(){ public void fly(){ System.out.println("用匿名內部類實現了Flyable這個介面,重寫了抽象方法"); } }; f.fly(); } } ``` (3)示例程式碼:用匿名內部類的匿名物件直接呼叫方法 ```java new Object(){ public void test(){ System.out.println("用匿名內部類的匿名物件直接呼叫方法") } }.test(); ``` (4)示例程式碼:用匿名內部類的匿名物件直接作為實參 ```java Student[] all = new Student[3]; all[0] = new Student("張三",23); all[1] = new Student("李四",22); all[2] = new Student("王五",20); //用匿名內部類的匿名物件直接作為實參 //這個匿名內部類實現了Comparator介面 //這個匿名內部類的物件,是定製比較器的物件 Arrays.sort(all, new Comparator(){ public int compare(Obeject o1, Object o2){ Student s1 = (Student)o1; Student s2 = (Student)o2; return s1.getAge() - s2.getAge(); } }); ``` ### 7.10.2 靜態內部類 1、語法格式 ```java 【修飾符】 class 外部類名 【extends 外部類的父類】 【implements 外部類的父介面們】{ 【其他修飾符】 static class 靜態內部類 【extends 靜態內部類自己的父類】 【implements 靜態內部類的父介面們】{ 靜態內部類的成員列表; } 外部類的其他成員列表; } ``` 2、 使用注意事項 (1)包含成員是否有要求: ​ 可以包含類的所有成員 (2)修飾符要求: * ​ 許可權修飾符:4種 * ​ 其他修飾符:abstractfinal3)使用外部類的成員上是否有要求 * ​ 只能使用外部類的靜態成員 (4)在外部類中使用靜態內部類是否有要求 * ​ 正常使用 (5)在外部類的外面使用靜態內部類是否有要求 ```java (1)如果使用的是靜態內部類的靜態成員 外部類名.靜態內部類名.靜態成員 (2)如果使用的是靜態內部類的非靜態成員 ①先建立靜態內部類的物件 外部類名.靜態內部類名 物件名 = new 外部類名.靜態內部類名(【實參列表】); ②通過物件呼叫非靜態成員 物件名.xxx ``` (6)位元組碼檔案形式:外部類名$靜態內部類名.class 3、示例程式碼 ```java class Outer{ private static int i = 10; static class Inner{ public void method(){ //... System.out.println(i);//可以 } public static void test(){ //... System.out.println(i);//可以 } } public void outMethod(){ Inner in = new Inner(); in.method(); } public static void outTest(){ Inner in = new Inner(); in.method(); } } class Test{ public static void main(String[] args){ Outer.Inner.test(); Outer.Inner in = new Outer.Inner(); in.method(); } } ``` ### 7.10.3 非靜態內部類 1、語法格式 ```java 【修飾符】 class 外部類名 【extends 外部類的父類】 【implements 外部類的父介面們】{ 【修飾符】 class 非靜態內部類 【extends 非靜態內部類自己的父類】 【implements 非靜態內部類的父介面們】{ 非靜態內部類的成員列表; } 外部類的其他成員列表; } ``` 2、 使用注意事項 (1)包含成員是否有要求: ​ 不允許出現靜態的成員 (2)修飾符要求 ​ 許可權修飾符:4種 ​ 其他修飾符:abstractfinal3)使用外部類的成員上是否有要求 ​ 都可以使用 (4)在外部類中使用非靜態內部類是否有要求 ​ 在外部類的靜態成員中不能使用非靜態內部類 (5)在外部類的外面使用非靜態內部類是否有要求 ```java //使用非靜態內部類的非靜態成員 //(1)建立外部類的物件 外部類名 物件名1 = new 外部類名(【實參列表】); //(2)通過外部類的物件去建立或獲取非靜態內部類的物件 //建立 外部類名.非靜態內部類名 物件名2 = 物件名1.new 非靜態內部類名(【實參列表】); //獲取 外部類名.非靜態內部類名 物件名2 = 物件名1.get非靜態內部類物件的方法(【實參列表】); //(3)通過非靜態內部類呼叫它的非靜態成員 物件名2.xxx ``` (6)位元組碼檔案形式:外部類名$非靜態內部類名.class 3、示例程式碼 ```java class Outer{ private static int i = 10; private int j = 20; class Inner{ public void method(){ //... System.out.println(i);//可以 System.out.println(j);//可以 } } public void outMethod(){ Inner in = new Inner(); in.method(); } public static void outTest(){ // Inner in = new Inner();//不可以 } public Inner getInner(){ return new Inner(); } } class Test{ public static void main(String[] args){ Outer out = new Outer(); Outer.Inner in1 = out.new Inner(); //建立 in1.method(); Outer.Inner in2 = out.getInner(); //獲取 in2.method(); } } ``` ### 7.10.4 區域性內部類 1、語法格式 ```java 【修飾符】 class 外部類名 【extends 外部類的父類】 【implements 外部類的父介面們】{ 【修飾符】 返回值型別 方法名(【形參列表】){ 【修飾符】 class 區域性內部類 【extends 區域性內部類自己的父類】 【implements 區域性內部類的父介面們】{ 區域性內部類的成員列表; } } 外部類的其他成員列表; } ``` 2、 使用注意事項 (1)包含成員是否有要求 ​ 不允許出現靜態的成員 (2)修飾符要求 ​ 許可權修飾符:不能 ​ 其他修飾符:abstractfinal3)使用外部類的成員等上是否有要求 ​ ①使用外部類的靜態成員:隨便用 ​ ②使用外部類的非靜態成員:能不能用要看所在的方法是否是靜態的 ​ ③使用所在方法的區域性變數:必須 final修飾的 (4)在外部類中使用區域性內部類是否有要求 ​ 有作用域 (5)在外部類的外面使用區域性內部類是否有要求 ​ 沒法使用 (6)位元組碼檔案形式:外部類名$編號區域性內部類名.class 3、示例程式碼 ```java class Outer{ private static int i = 10; private int j = 20; public void outMethod(){ class Inner{ public void method(){ //... System.out.println(i);//可以 System.out.println(j);//可以 } } Inner in = new Inner(); in.method(); } public static void outTest(){ final int k = 30; class Inner{ public void method(){ //... System.out.println(i);//可以 System.out.println(j);//不可以 System.out.println(k);//可以 } } Inner in = new Inner(); in.method(); } }