Table of Contents
Java內部類
1:什麼是內部類
內部類(Inner Classes)的概念是在 JDK1.1 版本中開始引入的。在 Java 中,允許在一個類(或方法、語句塊)的內部定義另一個類,稱爲內部類,有時也稱爲嵌套類(NestedClasses)。
內部類和外層封裝它的類之間存在邏輯上的所屬關係,一般只用在定義它的類或語句塊之內,實現一些沒有通用意義的功能邏輯,在外部引用它時必須給出完整的名稱。
內部類是一個有用的特徵,因爲它們允許將邏輯上同屬性的類組合到一起,並在另一個類中控制一個類的可視性。
public class MyFrame extends Thread {
Button myButton;
TextArea myTextArea;
int count;
public MyFrame(String title) {
super(title);
myButton = new Button("click me");
myTextArea = new TextArea();
add(myButton, BorderLayout.CENTER);
add(myTextArea, BorderLayout.NORTH);
ButtonListener bList = new ButtonListener();
myButton.addActionListener(bList);
}
class ButtonListener implements ActionListener { // 這裏定義了一個內部類
public void actionPerformed(ActionEvent e) {
count++;
myTextArea.setText("button clicked " + count + " times");
}
} // end of innerclass ButtonListener
public static void main(String args[]) {
MyFrame f = new MyFrame("Inner Class Frame");
f.setSize(300, 300);
f.setVisible(true);
}
}
2:內部類特點
- 1:嵌套類(內部類)可以體現邏輯上的從屬關係。同時對於其他類可以控制內部類對外不可見等。
- 2:外部類的成員變量作用域是整個外部類,包括嵌套類。但外部類不能訪問嵌套類的private 成員
- 3:邏輯上相關的類可以在一起,可以有效的實現信息隱藏。
- 4:內部類可以直接訪問外部類的成員。可以用此實現多繼承!
- 5:編譯後,內部類也被編譯爲單獨的類,不過名稱爲 outclass$inclass 的形式。
3:內部類的分類
內部類按照使用上可以分爲四種情形:
- (1)類級:成員式,有 static 修飾
- (2)對象級:成員式,普通,無 static 修飾
- (3)本地內部類:局部式
- (4)匿名級:局部式
3.1:成員內部類
class MyFrame extends Thread {
private int size;
public class Inner {
public void dostuff() {
size++;
}
}
public void testTheInner() {
Inner in = new Inner();
in.dostuff();
}
}
成員式內部類如同外部類的一個普通成員。成員式內部類的基本規則
- (1)可以有各種修飾符,可以用 4 種權限、static、final、abstract 定義(這點和普通的類是不同的);
- (2)若有 static 限定,就爲類級,否則爲對象級。類級可以通過外部類直接訪問;對象級需要先生成外部的對象後才能訪問。
- (3)內外部類不能同名
- (4)非靜態內部類中不能聲明任何 static 成員
- (5)內部類可以互相調用,如下:
class A {
// B、C 間可以互相調用
class B {
}
class C {
}
}
3.2:本地內部類
本地類(Local class)是定義在代碼塊中的類。它們只在定義它們的代碼塊中是可見的。
本地類有幾個重要特性:
- (1)僅在定義了它們的代碼塊中是可見的;
- (2)可以使用定義它們的代碼塊中的任何本地 final 變量;
- (3)本地類不可以是 static 的,裏邊也不能定義 static 成員。
- (4)本地類不可以用 public、private、protected 修飾,只能使用缺省的。
- (5)本地類可以是 abstract 的。
class MyFrame extends Thread {
public static final int TOTAL_NUMBER = 5;
public int id = 123;
public void t1() {
final int a = 15;
String s = "t1";
class Inner {
public void innerTest() {
System.out.println(TOTAL_NUMBER);
System.out.println(id);
System.out.println(a);
// System.out.println(s);不合法,只能訪問本地方法的final變量
}
}
new Inner().innerTest();
}
public static void main(String[] args) {
System.out.println("111");
}
}
3.3:匿名內部類
匿名內部類是本地內部類的一種特殊形式,也就是沒有變量名指向這個類實例,而且具體的類實現會寫在這個內部類裏面。把上面的例子改造一下,如下所示:
class MyFrame extends Thread {
public static final int TOTAL_NUMBER = 5;
public int id = 123;
public void t1() {
final int a = 15;
String s = "t1";
new Aclass() {
public void testA() {
System.out.println(TOTAL_NUMBER);
System.out.println(id);
System.out.println(a);
// System.out.println(s);不合法,只能訪問本地方法的final變量
}
}.testA();
}
public static void main(String[] args) {
Test t = new Test();
t.t1();
}
}
注意:匿名內部類是在一個語句裏面,所以後面需要加“;”。匿名類的規則:
- (1)匿名類沒有構造方法;
- (2)匿名類不能定義靜態的成員;
- (3)匿名類不能用 4 種權限、static、final、abstract 修飾;
- (4)只可以創建一個匿名類實例
4 內部類的規則
總結一下,內部類有如下特點:
- (1)類名稱只能用在定義過的範圍中,除非用在限定的名稱中。內部類的名稱必須與所嵌套的類不同。
- (2)內部類可以被定義在方法中。這條規則較簡單,它支配到所嵌套類方法的變量的訪問。任何變量,不論是本地變量還是正式參數,如果變量被標記爲 final,那麼,就可以被內部類中的方法訪問。
- (3)內部類可以使用所嵌套類的類變量和實例變量以及所嵌套的塊中的本地變量。
- (4)內部類可以被定義爲 abstract。
- (5)只有內部類可以被聲明爲 private 或 protected,以便防護它們不受來自外部類的訪問。訪問保護不阻止內部類使用其它類的任何成員,只要一個類嵌套另一個。
- (6)一個內部類可以作爲一個接口,由另一個內部類實現。
- (7)被自動地聲明爲 static 的內部類成爲頂層類。這些內部類失去了在本地範圍和其它內部類中使用數據或變量的能力。
- (8)內部類不能聲明任何 static 成員;只有頂層類可以聲明 static 成員。因此,一個需求 static 成員的內部類必須使用來自頂層類的成員。