面向對象複習,深入理解static關鍵字


面向對象複習

深刻理解,需要弄明白的問題:

         1,Static關鍵字的意思?

2,Static關鍵字可修飾什麼,基本使用規則?

3,Static關鍵字可修飾同步方法嗎?

4,靜態內部類和非靜態內部類的區別?

構造器中要注意的地方

         構造器不能聲明返回值類型,也不能用void聲明沒有返回值

如果加了,虛擬機會把“構造器”當作普通方法執行

構造器是否創建對象?

          大部分時候,程序是通過new關鍵字來爲java對象申請空間,然後通過構造器來初始化對象,所以事實上構造器只負責初始化對象

          下面兩種情況在創建對象時無序調用構造器:

1,  使用反序列化的方式恢復java對象

2,  使用clone方法複製java對象

首先:對象必須被序列化

第一種方式,就是將java對象保存到本地文件中,再通過讀取本地文件從而讀取java對象

代碼如下:

public class SerializableTest {
	public static void main(String[] args) throws Exception {
		// 將對象寫入硬盤中
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
				"F:\\3\\object1.txt"));
		Person p = new Person("zhangsan");
		oos.writeObject(p);
		oos.flush();
		// 從硬盤中讀取對象
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
				"F:\\3\\object1.txt"));
		Person p1 = (Person) ois.readObject();
		System.out.println(p.equals(p1));
		// 可以看出p和p1是兩個對象
		System.out.println(p == p1);
	}
}

可能破壞單例:爲了避免,應該給單例類提供readResolve()方法,返回已有的實例對象

第二種方式:使對象實現Cloneable接口,重寫clone()方法,就可以調用該對象的clone方法來創建對象 了

class Dog implements Cloneable {
	private String name;

	public Dog(String name) {
		System.out.println("調用帶有參數的構造方法");
		this.name = name;
	}

	public Object clone() {
		Dog dog = null;
		try {
			// 調用Object類的clone()方法
			dog = (Dog) super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return dog;
	}

	// 從寫equals方法
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj.getClass() == Dog.class) {
			Dog target = (Dog) obj;
			return target.name.equals(this.name);
		}
		return false;
	}
}

public class CloneTest {
	public static void main(String[] args) {
		// 調用帶參數的構造器
		Dog dog = new Dog("aoli");
		// 並沒有調用構造器
		Dog dog2 = (Dog) dog.clone();
		// 輸出true
		System.out.println(dog.equals(dog2));
		// 輸入false
		System.out.println(dog == dog2);
	}
}

方法重寫需要注意的問題

   子類無法訪問父類中的private方法和屬性,父類中定義的private方法不可能被子類重寫


如果不使用任何訪問控制符修飾方法,則就是默認的default修飾,該訪問權限限定在只能是與該類處於同一包內的其他類訪問,其他包中的子類依然無法訪問該方法

 

 

非靜態內部類:

         內部類可以直接訪問外部類的private成員

         內部類訪問外部類的局部變量時,局部變量需要final修飾(詳情見blog:java編程細節01)

 

創建非靜態內部類的對象時,需要創建一個外部類對象,作爲參數傳入內部類的構造器,因此,內部類的構造器的第一個形參總是外部類(所以說,非靜態內部類是依賴於外部類的)

 

一點:在外部類裏面派生內部類的子類是安全的,因爲派生出來的子類也是內部類,也是依賴於外部類的。

但是在外部類外面派生內部類的子類,需要在子類無參構造器中顯示調動父類指定的構造器

 

1, Static

表示靜態

2, static關鍵字可修飾成員變量和成員函數

成員變臉被static修飾後的特點:

           隨着類的加載而加載

           優先於對象存在

           被所有對象所共享(多個實例的靜態變量共享同一塊內存空間)

           可以直接被類名調用

使用規則:

           靜態方法只能訪問靜態成員

           靜態方法中不可以寫this,super關鍵字

 

Static只能用於修飾在類中定義的成員,包括:Field,方法,內部類,初始化塊,內部枚舉類

Static修飾方法時,該方法是靜態方法,屬於類,所以不能被子類重寫

 

3,Static關鍵字可修飾同步方法嗎?

         可以:

                   Static修飾的同步方法,拿到的鎖不是實例對象,而是該類的Class文件,就是當前類

4,靜態內部類與非靜態內部類的區別:

靜態內部類,不像非靜態內部類屬於外部類一樣,創建靜態內部類對象不需要先創建外部類實例對象,只要通過外部類名調用就行,如下:

class Outer {
	private String name;
	private static int age;

	public static class Inner {
		public void info() {
			// 可以直接訪問外部類的靜態成員
			System.out.println("age:" + age);
		}
	}
}

public class InnerTest {

	public static void main(String[] args){
		// 靜態內部類,不用先創建外部類實例對象
		Outer.Inner in = new Outer.Inner();
		in.info();
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章