——每天的寥寥幾筆,堅持下去,將會是一份沉甸甸的積累。
今天的筆記是有關核心一的接口部分(作爲個人筆記,就僅把我認爲重要的記錄了下來,一些較基礎的就跳過不寫了)。
1.實例域與類域的概念。實例域就是要new出來對象後對象所擁有的數據域,而類域則是類所有,編譯時就已經屬於類了。
接口不能含有實例域,也不能實現方法,僅能含有static final的數據域和未實現的public方法。
2.clone之深淺複製
所謂淺複製,就是說複製完的那個對象和原對象擁有一樣的引用,一個對象的數據段變了,另一個跟着一起變。
Person a = new Person("wangwu");
Person copy = a;
copy.setName("zhangsan");//此時a.getName="zhangsan"
所謂深複製,就是複製完兩個對象各歸各的,數據互不影響。
爲此,設計者還爲我們提供了一個接口cloneable。只要implements該接口,並恰當的覆寫從Object那裏繼承來的clone方法,就能通過調用clone方法實現深複製。這裏要強調下,clone方法是覆寫父類Object的方法,而不是實現接口的方法,因爲cloneable接口裏面並沒有clone方法,這裏implements這個接口僅僅是爲了做個標記,表明類設計者要進行克隆處理。
上面我着重加粗了“恰當的覆寫“,因爲這裏有陷阱,必須要小心。
首先明確,什麼是複製拷貝。就是將一個對象中的所有數據都複製另一個對象中,同時要滿足深複製。這裏就會有兩種情況:
一:如果對象中的數據域都是數值或基本數據類型,這樣的拷貝不會出錯。
二:如果對象中的數據域含有對象的引用(包含String類型),那麼要小心了,拷貝的結果會使複製出來的對象和原對象中的對象引用都會指向同一個區域,也就違背了深複製的原則。所以,需要單獨拿出來處理。
public Person clone(){
if(null == this) return null;
Person person = super.clone();//默認方法只對數值和基本數據類型起作用
person.name = "wagnwu".clone();//對於對象引用,克隆出一份,然後再自己手動設置成clone出的結果即可
person.birthday = (Date)birthday.clone();
return person;
}
3.內部類之局部、匿名、靜態內部類
內部類:定義在類中的類。
最重要的一個需要理解的點:
1.編譯時,內部類會被特殊對待,假設類A中有一內部類B,那麼編譯完成會生成一個A.class和一個A$B.class(內部類專屬字節碼),可以看出,結果都是class文件,因此,虛擬機完全不用管該class文件是內部類還是外部類,按照自己的規則處理class文件即可,這樣的設計方法是低耦合的,高效的。
2.不過,編譯完生成A$B的class文件會被添加一個構造函數,參數就是外部類的this引用,這樣的話,內部類就可以通過this對象直接對外部類的數據進行操作,實現了兩個類之間的交互。後面提到的靜態內部類,就是把this給拋掉了,因爲人家沒想着要訪問外部類的數據。
****後加的兩點,比較重要,不要忽視******
3.而外部類A.class還會生成多個靜態方法,返回值爲外部類的實例域,而方法參數爲外部類實例對象,這樣內部類就能調用這個靜態方法,通過該方法的返回值直接訪問外部類的私有數據,而不用通過公有的getter方法。
4.局部內部類不能用public,private訪問說明符修飾,因爲它的作用域限定在了聲明這個類的局部塊中。
局部內部類:
1.定義在方法體或代碼塊中
2.對外部世界完全隱藏,同時也能訪問外部類,並且,還能訪問final類型的局部變量,因爲編譯階段會在該局部類中生成相關構造函數和對應局部變量的拷貝,該構造函數可以給該拷貝變量賦值。
public void start(boolean beep){
class TimePrinter implements Actionlistener{
public void actionPerformed(ActionEvent event){
if(beep) dosomething //局部變量beep可以被內部類保存
}
}
Actionlistener listener = new TimePrinter();
}
class TalkingClock$TimePrinter{
TalkingClock$TimePrinter(TalkingClock,boolean);
public void actionPerformed(java.awt.actionEvent);
final boolean val$beep;//beep是外部類的局部變量
final TalkingClock this$0;//外部類引用
}
匿名內部類:
Person p1 = new Person("ace");//a person object
Person p2 = new Person("ace"){//an object of inner class
//data or methods
}
拓展技巧:雙括號初始化
ArrayList<String> f = new ArrayList<String>();
f.add("a");
f.add("b");
invite(f);
//兩種方式是等價的,但下面的方法更簡潔,因爲使用了匿名列表
invite(new ArrayList<String>(){
{
add("a");
add("b");
}
});
靜態內部類:
當僅僅爲了隱藏某一內部類,同時內部類也不需要訪問外部類(用不到外部類的this對象)時,可以將內部類聲明成靜態的,這樣可以實現完全的隱藏。
我cao,又這麼晚了。學生黨夠拼,也該睡了。。後面再完善吧。