《JAVA程式設計思想(第四版)》第七章(複用類)小結
組合語法
組合的小例子
組合很好理解,就是一個物件中的某個欄位是另一個物件.
String, 就是一個物件,所以接下來就是一種組合
public class Person{
private int id;
private String name; //一個String物件name.
//getter和setter
}
當然自定義的物件也可以,這種是我們經常用到的組合語法.
class page{ int num; String[] content; } public class Book { int bId; //書的編號 String bookName; //書名 String author; //作者 page[] pages; //每個書都有很多頁 //getter和setter方法 //構造器 }
組合語法很簡單,但是有幾個小知識點需要注意一下.
基本型別會被初始化(如int會初始化為0,boolean被初始化為false),而各個物件也是,不過他們是初始化為null,如果使用這個物件的方法,就會報錯:萬惡的空指標異常.如果想初始化這些物件,可以在程式碼的下列位置進行.
初始化問題
在定義物件的地方.
public class Person{
private int id;
private String name = "佚名"; //定義處進行初始化
//getter和setter
}
2.在類的構造器中,.(以上文的Person為例)
public class Person{ private int id; private String name; //一個String物件name. public Person(int id, String name) { super(); this.id = id; this.name = name; } public Person() { //構造器初始化 name = "佚名"; } //getter和setter }
3,就在正常使用這些物件前,"惰性初始化"
public class Person{ private int id; private String name; //一個String物件name. public String getName() { if(this.name == null) { name = "佚名"; //使用前初始化 } return name; } public void setName(String name) { this.name = name; } //id的getter和setter public static void main(String[] args) { Person p1 = new Person(); System.out.println(p1.getName()); } }
4.使用例項初始化
public class Person{
private int id;
private String name; //一個String物件name.
public Person() {}
//getter和setter
public static void main(String[] args) {
Person 老王 = new Person();
老王.name = new String(); //建立一個例項,[老王.name] 為這個例項的引用/控制代碼
System.out.println(老王.name);
}
}
繼承語法.
定義:繼承即使用extend關鍵字,如果class A extend B(A類繼承了B類,那麼A類將自動得到B類所有域和方法)
為了繼承,一般的規則是將所有的資料成員都指定為private,將所有的方法都指定為public,當然,在特殊情況下,必須做出調整,但一般都很有用.
過載與覆寫(重寫)
如果子類的同名方法的引數順序和型別在父類中包含,那麼就是覆寫,單純的重名,但是引數不同,即為過載.與寫在父類中的過載類似.
protected 關鍵字
在訪問控制權限裡,protected 關鍵字 :"類使用者而言,這是private的,但對於任何繼承於此類的子類或同一包內的類來說,它卻是可訪問的.":
儘管可以建立protected 域,但是最好的方式還是將域保持為private;你應當一直保留"更改底層實現"的權利.
final 關鍵字
使用範圍:
- 一個用不改變的編譯時常量.
- 一個在執行時被初始化的值,而你不希望它被改變.
- 不想被繼承的類.
- 不想被覆寫的方法.
根據慣例,既是static又是final的域用大寫表示,並使用下劃線分割各個單詞.
static final int VALUE_PI = 3.1415926
我們不能因為某資料是final的,就認為在編譯時可以知道它的值.final做的事不允許值被改變,而很多值都是執行時初始化的,所以無法得知..
final int randInt = random.nextInt(92);
無論什麼情況,編譯器都確保空白final在使用前必須被初始化.
final和private關鍵字
類中所有private方法都隱式地指定為是final的.由於無法取用private方法,所以也就無法覆蓋它.
向上轉型
繼承最重要的方面在於表現新類與基類之間的關係.可以用"新類是現有類的一種型別"來概括.
而實現在程式碼層面的一個意義是:能夠為這些子類們提供一套通用的模板,
也就是向上轉型.即從一個專用型別向較通用型別轉換
而子類中一定有基類的方法,所以,向上轉型時唯一發生的事情是丟失方法,而不是獲取它們.
繼承與初始化
繼承中有一個要點是初始化順序問題: 當需要初始化子類時,先初始化父類,如果父類還有父類,那麼先初始化父類的父類.(遞迴).
物件中所有的基本型別都會被設為預設值,物件引用被設為null----這是通過將物件記憶體設為二進位制零值而一舉生成的.
繼承與組合
- 組合和繼承都允許在新的類中放置子物件,組合是顯式地這樣做,而繼承則是隱式的.(具體情況按邏輯處理,一般都是正確的.)
- 組合一般是將現有型別作為新型別底層實現的一部分加以複用,而繼承複用的是介面.
- 如果你的設計變得過於複雜,通過將現有類拆分為更小的部分而新增更多的物件,通常會有所幫助.
- 儘管繼承在多處被很多人強調,但我們仍應該慎用這一技術,在使用前一定要確信使用該技術確實有效.
代理
代理(Proxy)是一種設計模式,提供了對目標物件另外的訪問方式;即通過代理物件訪問目標物件.這樣做的好處是:可以在目標物件實現的基礎上,增強額外的功能操作,即擴充套件目標物件的功能.
這裡使用到程式設計中的一個思想:不要隨意去修改別人已經寫好的程式碼或者方法,如果需改修改,可以通過代理的方式來擴充套件該方法舉個例子來說明代理的作用:假設我們想邀請一位明星,那麼並不是直接連線明星,而是聯絡明星的經紀人,來達到同樣的目的.明星就是一個目標物件,他只要負責活動中的節目,而其他瑣碎的事情就交給他的代理人(經紀人)來解決.這就是代理思想在現實中的一個例子
繼承和組合都可以實現代理.