《JAVA編程思想》5分鐘速成:第7章(複用類)

第7章 複用類

7.1 名稱屏蔽:

在C++中,如果基類擁有一個已被多次重載的方法名稱,那麼在其派生類中重新定義該方法名稱,就會屏蔽其基類中的任何版本,這叫做名稱屏蔽。但是在Java中,就種情況下,不會發生名稱屏蔽,即無論在派生類還是在基類中對方法進行定義,重載機制都可以正常工作。


7.2 @Override註解

Java SE5新增加了@Override註解,可以把它當作關鍵字來用,它的作用是告訴編譯器我想重寫這個方法,因為Java不會產生名稱屏蔽,所以如果我不留心重載了,編譯器就會報錯來告訴我違背了我的初衷。


7.3 final關鍵字

Java的關鍵字final:“這是無法改變的。”不想改變可能出於兩種理由:設計或效率。可能使用到final的三種情況:數據、方法和類。


7.3.1 final數據

final基本數據類型變量:這樣編譯器可在編譯時執行計算式,從而減輕了運行時負擔(提高效率)。

備註1:編譯期常量在定義時必須對其賦值。

備註2:空白final:編譯期常量在聲明時可以不賦(此時叫空白final),但必須在構造器中賦值,所以final域在使用前總是被初始化。

final對象引用:引用恆定不變,即一旦引用初始化指向一個對象,就無法再把它改變為指向另一個引用,但對象其自身是可以被修改的。這種情形同樣適用數組,因為如前面所述,Java數組也可(看作)是引用。

final參數:指明為final的方法參數,意味著方法內只能讀而不能修改參數,這一特性主要用來向匿名內部類傳遞數據。


7.3.2 final方法

使用final方法的原因有兩個:

1. 鎖定方法:以防任何繼承類修改它的含義。這是出於設計的考慮。

2. 效率:在Java早期版本中,方法聲明為final,就是同意編譯器針對該方法的所有調用都轉為內嵌調用。而在Java SE5/6時,應該讓編譯器和JVM雲處理效率問題,只有在想要明確禁止覆蓋時,才將方法設置為final的。


final和private關鍵字

類中所有的private方法都隱式地指定為是final的。由於無法取用private方法,所以也就無法覆蓋它。

派生類中試圖“覆蓋”父類中一個private方法(隱含是final的),似乎奏效,編譯器不會出錯,但實際上只是在派生類中生成了一個新的方法,此時並沒有覆蓋父類的private方法。


7.3.3 final類

final類:對該類的設計永不需要變動,或者出於安全的考慮,你不希望它有子類。因為final類禁止繼承,所以final類中所有的方法都隱式指定為是final的,因為無法覆蓋它們。在final類中可以給方法添加final修飾詞,但這不會增添任何意義。


7.3.4 有關final的忠告

在設計類時,將方法指明是final的,應該說是明智的。

- Java1.0/1.1中Vector類中的方法均沒有設計成final的,然後Statck繼承了Vector,就是說Stack是個Vector,這從邏輯觀點看是不正確的,還有Vector中的addElement()和elementAt()是同步的,導致執行開銷大,可能會抹煞final的好處。所以Vector的設計不合理,現代Java的容器ArrayList替代了Vector。ArrayList要合理得多,但遺憾的是仍然存在用舊容器庫編寫新程序代碼的情況。

- Java1.0/1.1中的Hashtable類也是不包含任何final方法。現代Java的容器庫用HashMap代替了Hastable。


7.4. 初始化及類的加載

7.4.1 類的加載

Java採用了一種不同的對類加載的方式,Java每個類的編譯代碼都存在於它自己的獨立的文件中(.class文件)。該文件只在其代碼需要被使用時才會被加載(That file isn’t loaded until the code is needed)。


通常,可以說“類的代碼在初次使用時才加載。”,包括兩個場景:

場景1:這通常是指加載發生於構造類的第一個對象之時;

場景2:當訪問static域或static方法時,也會發生加載。(構造器也是static方法,儘管static關鍵字並沒有地寫出來。因此更準確地講,++類是在其任何static成員被訪問時加載的++。)


7.4.2 初始化

初次使用之處也是staic初始化發生之處。

所有的static對象和static代碼段都會在加載時依程序中的順序(即,定義類時的書寫順序)而依次初始化。

當然,定義為static的東西只會被初始化一次。


《JAVA編程思想》5分鐘速成:第7章(複用類)


分享到:


相關文章: