Java內部類詳解(三)

四、靜態內部類與非靜態的區別

首先,靜態內部類實際上與普通類(即類名必須與文件名一樣的頂級類)一樣,只是靜態內部類在某一類的內部定義了而已,既然是類,要想使用就必須實例化。概念上與靜態變量、靜態方法是不一樣的,不要被“靜態”兩個字迷惑了(不要以爲凡是靜態的東西就不需要實例化就可以直接使用,靜態內部類是有區別),而且只有靜態內部類,而沒有靜態類(頂級類)的概念。例如,下面定義類是錯誤的:

public static class TestClass { // 此寫法錯誤,不存在靜態類,編譯不通過

	public void test() {
		
	}
}

如果你不需要內部類對象與其外部類對象之間有聯繫,那你可以將內部類聲明爲static。這通常稱爲嵌套類(nested class)。Static Nested Class是被聲明爲靜態(static)的內部類,它可以不依賴於外部類實例被實例化。而通常的內部類需要在外部類實例化後才能實例化。想要理解static應用於內部類時的含義,你就必須記住,普通的內部類對象隱含地保存了一個引用,指向創建它的外部類對象。然而,當內部類是static的時,就不是這樣了。嵌套類意味着: 

1. 嵌套類的對象,並不需要其外部類的對象。 

2. 不能從嵌套類的對象中訪問非靜態的外部類對象。 

如下所示代碼爲定義一個靜態嵌套類:

public class StaticTest {
	private static String name = "woobo";
	private String num = "X001";

	static class Person { // 靜態內部類可以用public,protected,private修飾

		// 靜態內部類中可以定義靜態或者非靜態的成員
		private String address = "China";

		private static String x = "as";
		public String mail = "[email protected]";// 內部類公有成員

		public void display() {
			// System.out.println(num);//不能直接訪問外部類的非靜態成員

			// 靜態內部類不能訪問外部類的非靜態成員(包括非靜態變量和非靜態方法)
			System.out.println(name);// 只能直接訪問外部類的靜態成員

			// 靜態內部類只能訪問外部類的靜態成員(包括靜態變量和靜態方法)
			System.out.println("Inner " + address);// 訪問本內部類成員。
		}
	}

	public void printInfo() {
		Person person = new Person();

		// 外部類訪問內部類的非靜態成員:實例化內部類即可
		person.display();

		// System.out.println(mail);//不可訪問
		// System.out.println(address);//不可訪問
		System.out.println(person.address);// 可以訪問內部類的私有成員

		System.out.println(Person.x);// 外部類訪問內部類的靜態成員:內部類.靜態成員
		System.out.println(person.mail);// 可以訪問內部類的公有成員
	}

	public static void main(String[] args) {
		StaticTest staticTest = new StaticTest();
		staticTest.printInfo();
	}
}

總結:

1. 靜態內部類可以有靜態成員(方法,屬性),而非靜態內部類則不能有靜態成員(方法,屬性)。

2. 靜態內部類只能夠訪問外部類的靜態成員,而非靜態內部類則可以訪問外部類的所有成員(方法,屬性)。

3. 實例化一個非靜態的內部類的方法:

a. 先生成一個外部類對象實例

OutClassTest oc1 = new OutClassTest();

b. 通過外部類的對象實例生成內部類對象

OutClassTest.InnerClass no_static_inner = oc1.new InnerClass();

4. 實例化一個靜態內部類的方法:

a. 不依賴於外部類的實例,直接實例化內部類對象

OutClassTest.InnerStaticClass inner = new OutClassTest.InnerStaticClass();

b. 調用內部靜態類的方法或靜態變量,通過類名直接調用

OutClassTest.InnerStaticClass.static_value

OutClassTest.InnerStaticClass.getMessage()


最後,我再告訴大家,接口雖然不能有任何實現,但內部類(無論是靜態的還是非靜態的內部類)卻可以作爲接口的一部分,例如:

public interface TestInterface {

	void testMethod();
	
	static class TestInnerClass implements TestInterface {// 並不是非要實現TestInterface,這裏可以做任何事情。

		@Override
		public void testMethod() {
			System.out.println("測試");
		}
		
	}
}
class Test {

	public static void main(String[] args) {
		TestInnerClass testClass = new TestInterface.TestInnerClass();
		testClass.testMethod();
	}
}



發佈了110 篇原創文章 · 獲贊 197 · 訪問量 320萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章