1. 程式人生 > >java學習筆記(三)內部類及靜態內部類

java學習筆記(三)內部類及靜態內部類

內部類的建立
   內部類 物件名 = 外部類物件.new 內部類();
   外部類是不能使用內部類的成員和 方法
   如果外部類和內部類具有相同的成員變數或方法,內部類預設
   訪問自己的成員變數 或方法,如果要訪問外部類的成員變數,
   可以使用this關鍵字。


//外部類HelloWorld
public class HelloWorld{
    
    //外部類的私有屬性name
    private String name = "imooc";
    
    //外部類的成員屬性
    int age = 20;
    
	//成員內部類Inner
	public class Inner {
		String name = "愛慕課";
        //內部類中的方法
		public void show() { 
			System.out.println("外部類中的name:" +    this.name              );
			System.out.println("內部類中的name:" +      name            );
			System.out.println("外部類中的age:" + age);
		}
	}
    
	//測試成員內部類
	public static void main(String[] args) {
        
        //建立外部類的物件
		HelloWorld o = new HelloWorld (); 
        
        //建立內部類的物件
		Inner inn =  o.new Inner();            ;
        
        //呼叫內部類物件的show方法
		inn.show();
	}
}

靜態內部類:

  靜態內部類是 static 修飾的內部類,這種內部類的特點是:

1、 靜態內部類不能直接訪問外部類的非靜態成員,但可以通過 new 外部類().成員 的方式訪問 

2、 如果外部類的靜態成員與內部類的成員名稱相同,可通過“類名.靜態成員”訪問外部類的靜態成員;如果外部類的靜態成員與內部類的成員名稱不相同,則可通過“成員名”直接呼叫外部類的靜態成員

3、 建立靜態內部類的物件時,不需要外部類的物件,可以直接建立 內部類 物件名= new 內部類();

public class HelloWorld {
    
    // 外部類中的靜態變數score
    private static int score = 84;
    
    // 建立靜態內部類
	public static class SInner {
        // 內部類中的變數score
        int score = 91;
        
		public void show() {
			System.out.println("訪問外部類中的score:" +   HelloWorld.score);
			System.out.println("訪問內部類中的score:" + score);
		}
	}

	// 測試靜態內部類
	public static void main(String[] args) {
		// 直接建立內部類的物件
        SInner si = new SInner();
        // 呼叫show方法
		si.show();
	}
}

靜態變數(類)與非靜態變數(類)的區別以及為什麼要使用靜態變數(來源:imooc問答區):

一般靜態變數都是公用的、全域性的,程式一啟動就會在記憶體開闢一塊空間,存放它們。靜態的不必例項化就能直接使用,是說在沒有生成任何物件時就能運用該方法,所以靜態方法裡不能對非靜態的成員變數做操作。一般靜態方法操作靜態成員變數或全域性變數。

要搞清楚這個問題,我們需要清楚他們之間有什麼區別,有什麼優勢和劣勢。

首先看看靜態與非靜態方法的區別:

靜態方法                    |  例項方法

1、靜態方法可以通過“類.方法()”呼叫        | 要在物件例項化後使用物件呼叫

2、只能使用靜態變數和區域性變數        | 所有變數都可以使用

3、靜態方法不能被子類重寫          | 例項方法可以

4、介面不能定義靜態方法             | 例項方法可以

從上面區別來看,靜態方法只有一個優勢,就是呼叫的時候不用例項化,其他情況下跟例項方法相比都是處於劣勢。那麼我們在什麼情況下會使用到靜態方法?相信大家第一時間會想到一樣的東西,工具類Util。工具類給我們開發帶來了大大的方便,歸根到底是“不用例項化就能用”的功勞。這是靜態方法的一個優勢。

而靜態方法的劣勢也很明顯,侷限性很大,不能重寫,不能引用普通變數,介面不能定義等等。。。可能還有很多我沒列舉出來。

那究竟什麼時候該用靜態方法?我們就要最大化利用其優勢而避其缺點:

1、一個方法完成一個獨立的功能,而且不會干擾到其他方法或變數,則即使刪掉這個方法,對其他東西都沒有任何影響。

2、不依賴構造方法,不依賴介面,不依賴繼承。(這也是為什麼越學面向物件,越會糾結這個問題)

舉個例子:String類即使刪掉 static valueOf(Object obj)方法,也不會影響例項方法chatAt(int index)的使用。當然它可能會影響其他過載的valueOf方法。

至於現在網上很多資料都有一個誤區,就是說靜態方法一開始載入,會佔用記憶體,而例項方法不會。這個說話其實是錯誤的,它們都是一樣一開始就會載入,而且只會佔用一份記憶體。因為方法不是變數,它只需要有一份記憶體就夠了。而變數則不一樣

-----------------------------------------------------------------------------------------------------------------------------------------------------------

下面來看看靜態變數與非靜態變數

靜態變數                    |  非靜態變數

1、可以通過“類.變數”來引用。          | 只能通過例項物件來引用。

2、程式執行時分配記憶體            |  類例項化時分配記憶體。

3、只有一份記憶體被分配            |  有多少個類被例項化,就有多少個該類的變數那麼多份記憶體被分配。

4、靜態變數定義後必須宣告初始化         | 非靜態變數可以延遲初始化。

其他.....

很明顯,靜態變數擁有的優勢不少,第一點不用說。第2、3點可以利用它來做一個整個程式的全域性變數,因為任何修改都只會指向同一份記憶體。

而第3點優勢恰好就是我們的“餓漢式單例模式”的一個最簡單的實現。