1、 內部類:
是類中五大成分之一(成員變量、方法、構造函數、內部類、代碼塊),如果一個類定義在另一個 類的內部,這個類就是內部類。
場景:當一個類的內部,包含了一個完整的事物,且這個事物沒有必要單獨設計時,就可以把這個事物設計成內部類。
內部類的四種形式:
成員內部類:了解
靜態內部類:了解
局部內部類:了解
匿名內部類:重點
成員內部類:
就是類中的一個普通成員,類似前面我們學過的普通的成員變量、成員方法。
Outer類:
內含內部類:
package cn.ensource.d1_inner_class1;public class Outer {private int age = 99;public static String a;// 普通成員內部類public class Inner{private String name;private int age = 88;public static String schoolName; // JDK16才支持靜態成員的public void test() {System.out.println(age);System.out.println(a);int age = 66;// 66System.out.println(age);// 88System.out.println(this.age);// 99System.out.println(Outer.this.age);}public String getName() {return name;}public void setName(String name) {this.name = name;}}
}
測試類:
package cn.ensource.d1_inner_class1;public class Test {public static void main(String[] args) {// 目標:了解成員內部類Outer.Inner in = new Outer().new Inner();in.test();}
}
注意:
JDK16之前,成員內部類中不能定義靜態成員,JDK16開始也可以定義靜態成員了。
創建對象的格式:
成員內部類中訪問其他成員的特點:
1)和前面學過的實例方法一樣,成員內部類的實例方法中,同樣可以直接訪問外部類的實例成員、靜態成員。
2)可以在成員內部類的實例方法中,拿到當前外部類對象,格式: 外部類名.this
靜態內部類:
所謂靜態內部類,有static修飾符的內部類,屬于外部類自己持有。
靜態內部類是外部類持有的。
Outer類:包含靜態內部類:
package cn.ensource.d1_inner_class2;public class Outer {private int age;public static String schoolName;// 靜態內部類public static class Inner {private String name;public static int a;public void test() {
// System.out.println(age); // 只能通過外部類對象訪問System.out.println(schoolName);}public String getName() {return name;}public void setName(String name) {this.name = name;}public static int getA() {return a;}public static void setA(int a) {Inner.a = a;}}public static void test2() {System.out.println(schoolName);
// System.out.println(age);}
}
?測試類:
package cn.ensource.d1_inner_class2;public class Test {public static void main(String[] args) {// 目標:了解靜態內部類Outer.Inner in = new Outer.Inner();in.getName();in.test();}
}
特別要注意的是:
可以直接訪問外部類的靜態成員,不可以直接訪問外部類的實例成員。
外部類的實例成員只能通過外部類對象來訪問。
局部內部類:
局部內部類是定義在方法中,代碼塊中,構造器等執行體中。
匿名內部類:(重點)
就是一種特殊的局部內部類;所謂匿名:指的是程序員不需要為這個類聲明名字。
package d3_inner_class3;public class Test {public static void main(String[] args) {// 目標:掌握匿名內部類,并掌握其作用Animal a = new Cat(); // 創建子類對象a.cry();}
}class Cat extends Animal {@Overridepublic void cry() {System.out.println("喵喵~");}
}abstract class Animal {public abstract void cry();
}
進化:
package d3_inner_class3;public class Test {public static void main(String[] args) {// 目標:掌握匿名內部類,并掌握其作用
// Animal a = new Cat(); // 創建子類對象
// a.cry();// 我們只要創建一下子類對象就可以了,不需要經常性的創建子類// 匿名內部類// 把這個匿名內部類編譯成一個子類,然后會立即創建一個子類出來Animal a = new Animal() {@Overridepublic void cry() {System.out.println("喵喵~");}};a.cry();}
}class Cat extends Animal {@Overridepublic void cry() {System.out.println("喵喵~");}
}abstract class Animal {public abstract void cry();
}
匿名內部類的概念。
匿名內部類本質上是不是一個子類呢?
反編譯可以看到這個匿名類是Animal的子類。
編譯生成一個匿名的構造方法。
并且有內部方法cry方法。
特點:匿名內部類本質就是一個子類,并會立即創建出一個子類對象。
作用:用于更方便地創建一個子類對象。
匿名內部類的常見使用場景:
通常作為一個參數傳遞給方法。
package d3_inner_class3;public class Test2 {public static void main(String[] args) {// 目標:掌握匿名內部類的使用場景:Swimming s1 = new Swimming(){@Overridepublic void swim() {System.out.println("狗游泳!");}};go(s1);Swimming s2 = new Swimming() {@Overridepublic void swim() {System.out.println("貓游泳!");}};go(s2);}// 設計一個方法,可以接收swimming接口的一切實現類對象進來參加游泳比賽// go 表示開始參加比賽public static void go(Swimming s) {System.out.println("開始----------");s.swim();}
}// 貓和狗都要參加有用比賽
interface Swimming{void swim();
}
匿名內部類有啥特點:
匿名內部類本質上就是一個子類,并會立即創建出一個子類對象。
匿名內部類有啥作用、應用場景?
可以更方便創建出一個子類對象。
匿名內部類通常作為一個參數傳遞給方法。
拓展:
package cn.ensource.d4_inner_class5;import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;public class Test {public static void main(String[] args) {// 拓展:內部類在開發中的真實使用場景// GUI編程:// 1. 創建窗口JFrame win = new JFrame("登錄");JPanel panel = new JPanel();win.add(panel);JButton btn = new JButton("登錄");panel.add(btn);// 給按鈕綁定單擊事件監聽器// 調別人的匿名內部類,需要用的時候才用// 真實應用場景btn.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {JOptionPane.showMessageDialog(win, "登錄一下");}});win.setSize(400, 400);win.setLocationRelativeTo(null);win.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);win.setVisible(true);}
}
最終目的是為了簡化代碼。
箭頭語法后面會講得。
匿名內部類,我們需要的時候才會用。