javaSE之各種內部類詳解
文章目錄
在java中,內部類主要分為四種:
- 成員內部類
- 靜態內部類
- 方法內部類
- 匿名內部類
成員內部類
成員內部類要注意:
- 成員內部類中不能存在任何static的變數和方法
- 成員內部類是依附於外圍類的,所以只有先建立了外圍類才能夠建立內部類
舉個例子:
public class Test{
public Test(){
System.out.println ("這是一個類");
}
public static void main(String[] args) {
new Test();
new Test().new Test2().test();
}
class Test2{
public void test(){
System.out.println("這是一個成員內部類");
}
}
}
Test2在Test這個類裡面,更像是Test的成員,所以Test2是成員內部類,而Test是外部類,成員內部類可以無條件的訪問外部類的所有成員屬性和成員方法。包括私有成員和靜態成員。
執行結果如下:
不過要注意的是,當成員內部類擁有和外部類同名的成員變數或者方法時,會發生隱藏現象,即預設情況下訪問的是成員內部類的成員。如果要訪問外部類的同名成員,需要以下面的形式進行訪問:
外部類.this.成員變數
外部類.this.成員方法
雖然成員內部類可以無條件地訪問外部類的成員,而外部類想訪問成員內部類的成員卻不是這麼隨心所欲了。在外部類中如果要訪問成員內部類的成員,必須先建立一個成員內部類的物件
,再通過指向這個物件的引用來訪問:
靜態內部類
靜態內部類就是用static修飾的內部類,它區別的其他內部類的地方在於,靜態內部類不依賴於外圍類,可以直接建立,當然靜態內部類不可以使用任何外部類的非靜態屬性和方法
,但內部類可以。
這一點其實也很容易想,一旦這個類被static所修飾,那麼這個類就不依賴於外部類了,這樣的話,可以直接訪問這個類,一旦在靜態內部類中引用了外部類的非靜態屬性和成員的話,就會與外部的非靜態所矛盾,因此在靜態內部類中不能使用任何外部類的非靜態屬性和方法。
外部類的建立語法:
外部類.內部類 內部類物件 = new 外部類.內部類();
還是看個例子吧:
class Outer{
private static String msg = "Hello World" ;
static class Inner{ //定義一個靜態內部類
public void print(){ //此時只能使用外部類中的static操作
System.out.println(msg); //呼叫msg屬性
}
}
//在外部類中定義一個方法
public void fun(){
Inner in = new Inner(); //內部類物件
in.print(); // 內部類提供的print()方法
}
}
public class Test{
public static void main(String[] args) {
Outer.Inner in = new Outer.Inner();//這條語句非常重要
in.print();
}
}
靜態內部類的定義很簡單,就是在內部類前加上static關鍵字,而需要掌握的是在外部類中如何使用靜態內部類。
方法內部類
方法內部類,從名字上就大概知道了它的定義了,就是在外部方法裡面定義的類
要注意的是方法內部類只能在方法中使用,出了這個方法就無法再繼續使用
那麼為什麼會需要方法內部類呢?主要是為了方便我們去解決一些比較複雜的問題,起到一個輔助的作用,但同時又不想讓別的類訪問到這個類,就引入了局部內部類的概念。
需要注意以下幾點:
- 區域性內類不允許使用訪問許可權修飾符 public private protected 均不允許
- 區域性內部類對外完全隱藏,除了建立這個類的方法可以訪問它其他的地方是不允許訪問的。
- 區域性內部類要想使用方法形參,該形參必須用final宣告(JDK8形參變為隱式final宣告).
還是看例子理解:
class Outter {
private int num;
public void display(int test) {//只作用於方法內部
class Inner {//定義了一個方法內部類
private void fun() {
num++;
System.out.println(num);
System.out.println(test);
}
}
new Inner().fun();//在這個方法裡面使用方法內部類
}
}
public class Test {
public static void main(String[] args) {
Outter out = new Outter();
out.display(20);
}
}
匿名內部類
匿名內部類其實就是一個沒有名字的方法內部類,也是在外部類的方法裡面的,符合方法內部類的所有約束,但同時應注意以下幾點:
- 匿名內部類是沒有訪問修飾符的。
- 匿名內部類必須繼承一個抽象類或者實現一個介面
- 匿名內部類中不能存在任何靜態成員或方法
- 匿名內部類是沒有構造方法的,因為它沒有類名。
- 與區域性內部相同匿名內部類也可以引用方法形參。此形參也必須宣告為 final
下面簡單解釋一下:
1.沒有訪問修飾符,這一點應該很容易理解,因為匿名內部類是在方法內部的,外部是無法訪問的,所以無需訪問修飾符
2.匿名內部類中不能存在任何靜態成員,這一點與成員內部類是一樣的,上面解釋過,這裡不多說
3.沒有構造方法,這個我們想想構造方法的定義,構造方法名必須與類名相同,而匿名內部類根本就沒有類名,自然也就沒有構造方法了
例子:
interface MyInterface {
void test();
}
class Outter {
private int num;
public void display(int para) {
// 匿名內部類,實現了MyInterface介面
new MyInterface(){
@Override
public void test() {
System.out.println("匿名內部類"+para);
}
}.test();
}
}
public class Test {
public static void main(String[] args) {
Outter outter = new Outter();
outter.display(20);
}
}