内部類:寫在其他内部的類為内部類,如生物類中包含植物類、動物類等,則植物類就可以定義為内部類,而生物類為外部類。内部類有四種:成員内部類、靜态内部類、局部内部類、匿名内部類
1、内部類(嵌套類)
(1)成員内部類
建立Animal内部類,外部類為Biology
class Biology{
public int age;
public String name;
public class Plants {
public String colour;
public Plants(int a, String n, String c) {
age = a;// 外部類的成員變量
name = n;
colour = c;// 内部類的成員變量
}
public void display() {
System.out.println("植物的名字是:" + name + "\n" + "顔色為:" + colour);
}
}
}
建立測試類:
public class Test {
public static void main(String[] args) {
Biology.Plants plants = new Biology().new Plants(1, "蒲公英", "黃色");// 内部類的通路
plants.display(); } }

可以看出,内部類的執行個體化需要依賴于外部類執行個體被執行個體化
- 可以通路它的外部類的所有成員變量和方法,不管是靜态的還是非靜态的都可以
(2)靜态内部類
Static Nested Class是被聲明為靜态(static)的内部類,它可以不依賴于外部類執行個體被執行個體化。而通常的内部類需要在外部類執行個體化後才能執行個體化
- 靜态嵌套類不是其外部類的真正成員,它與外部類級别相同
- 被編譯成一個完全獨立的.class檔案
- 隻可以通路外部類的靜态成員和靜态方法,包括了私有的靜态成員和方法
- 外部類被裝載的時候,靜态内部類不會被裝載
- 執行個體建立方式
OuterClass.StaticNestedClass nestedObject =new OuterClass.StaticNestedClass();
舉例
public class StaticInnerClass {
public static class InnerClass{
private String string="早上好";
public void say(){
System.out.println(string);
}
}
public void say(){
System.out.println("你好");
}
public static void main(String[] args) {
InnerClass InnerClass= new StaticInnerClass.InnerClass();
InnerClass.say();
StaticInnerClass staticInnerClass=new StaticInnerClass();
staticInnerClass.say();
}
}
2、局部内部類
局部内部類(放在方法裡面的類),調用規則為:
public class Outer {
public void out{
class Inner{
public void Inner(){
System.out.println()
}
}
}
}
隻有out()方法能夠使用局部内部類Inner。
3、匿名内部類
(1)如果用普通方法創建一個動物抽象類,再建立一個Dog類,繼承動物類,過程如下:
動物類:
abstract class Animal {
String name;
String colour;
abstract void show();
}
Dog類:
public class Dog extends Animal {
public Dog(String name, String colour) {
this.name = name;
this.colour = colour;
}
void show() {
System.out.println("狗的名字是" + name + ", 它是" + colour + "的");
}
}
測試類:
public class Test {
public static void main(String[] args) {
Dog d=new Dog("Tom","黑色");
d.show();
}
}
(2)如果用匿名内部類,操作過程如下
建立Animal抽象類:
abstract class Animal {
String name;
String colour;
abstract void show(String n,String a);
}
public class Test {
public static void main(String[] args) {
Animal a=new Animal(){
public void show(String n,String c) {
name=n;
colour=c;
System.out.println("狗的名字是" + name + ", 它是" + colour + "的");
}
};
a.show("Jack","灰色");
}
}
可以看出,我們直接将抽象類的子類隐藏常在了測試類中,沒有用到抽象類的實作類,減少了代碼的書寫。但是匿名内部類隻能使用一次。
(3)匿名内部類舉例:定義一個按鈕,按鈕被按下的時候觸發事件
public class SwingTest {
public static void main(String[] args) {
JFrame jFrame=new JFrame("My JFrame");
JButton jButton=new JButton("My JButton");
jButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Button Pressed!!");
}
});
jFrame.add(jButton);
jFrame.pack();
jFrame.setVisible(true);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
(4)總結
- 匿名内部類沒有名字,不使用關鍵字class, extends, implements, 沒有構造方法,是以匿名内部類隻能使用一次,可以簡化代碼。它不能extends(繼承)其它類,但一個内部類可以作為一個接口,由另一個内部類實作
- 匿名内部類隐式地繼承了一個父類或者實作了一個接口
前提:必須繼承一個父類或實作一個接口,匿名内部類必須實作接口或抽象類的所有方法
可以繼承其他類或實作其他接口,在Swing程式設計中常用此方式來實作事件監聽和回調。
可以通路建立它的外部類對象的成員,包括私有成員
4、匿名對象
(1)概念:即隐藏了對象的名字
(2)建立方式:
如建立普通對象:Person p=new Person();
建立匿名對象:new Person();
(3)适用場景:隻使用一次對象,用完之後就變成了垃圾,被回收。如;new person().run();
(4)好處:節省代碼量
5、普通外部類與内部類的差別
(1)在編譯之後内部類會被編譯成獨立的 .class 檔案,但是前面有外部類的類名和 $ 符号。
(2)在外部類的靜态方法和外部類以外的其他類中,必須通過外部類的執行個體建立内部類的執行個體。在内部類内,可以直接建立内部類的執行個體。
6、内部類的優點
每個人都會有一段異常艱難的時光 。
生活的壓力 , 工作的失意 , 學業的壓力。
愛的惶惶不可終日。
挺過來的 ,人生就會豁然開朗。
挺不過來的 ,時間也會教你 ,怎麼與它們握手言和 ,是以不必害怕的。
——楊绛