面向對象複習
深刻理解,需要弄明白的問題:
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();
}
}