1. 程式人生 > >javaSE之各種內部類詳解

javaSE之各種內部類詳解

文章目錄


在java中,內部類主要分為四種:

  • 成員內部類
  • 靜態內部類
  • 方法內部類
  • 匿名內部類

成員內部類

成員內部類要注意:

  1. 成員內部類中不能存在任何static的變數和方法
  2. 成員內部類是依附於外圍類的,所以只有先建立了外圍類才能夠建立內部類

舉個例子:

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關鍵字,而需要掌握的是在外部類中如何使用靜態內部類。

方法內部類

方法內部類,從名字上就大概知道了它的定義了,就是在外部方法裡面定義的類
要注意的是方法內部類只能在方法中使用,出了這個方法就無法再繼續使用
那麼為什麼會需要方法內部類呢?主要是為了方便我們去解決一些比較複雜的問題,起到一個輔助的作用,但同時又不想讓別的類訪問到這個類,就引入了局部內部類的概念。

需要注意以下幾點:

  1. 區域性內類不允許使用訪問許可權修飾符 public private protected 均不允許
  2. 區域性內部類對外完全隱藏,除了建立這個類的方法可以訪問它其他的地方是不允許訪問的。
  3. 區域性內部類要想使用方法形參,該形參必須用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);
	}
}

匿名內部類

匿名內部類其實就是一個沒有名字的方法內部類,也是在外部類的方法裡面的,符合方法內部類的所有約束,但同時應注意以下幾點:

  1. 匿名內部類是沒有訪問修飾符的。
  2. 匿名內部類必須繼承一個抽象類或者實現一個介面
  3. 匿名內部類中不能存在任何靜態成員或方法
  4. 匿名內部類是沒有構造方法的,因為它沒有類名。
  5. 與區域性內部相同匿名內部類也可以引用方法形參。此形參也必須宣告為 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);
	}
}