跳到主要內容

物件導向觀念深入5 - 封裝 (Encapsulation)、final、is-a VS has-a

 


頻道需要你的支持,謝謝你成為我們的會員(加入會員)

影片1  package 的基本觀念。 



影片2  package 的宣告與建立。 



影片3 成員存取的方式與存取限制 private。 



影片4  存取限制 (default, protected, public )、static import 、 override 與存取限制的關係



影片5 針對開放對象為物件與類別使用者的封裝實例演練



影片6 針對開放對象為子類別使用者的封裝實例演練



影片7 Factory method, Singleton, Immutable Design pattern 介紹與實作



影片8 Builder Design pattern 介紹與實作



影片9 final 變數的宣告與指派 & final 方法的 Override 與多型應用



影片10 非必要, 不要繼承? 多型不安全? Is - a VS Has -a 那一種比較好? 



影片11 介用簡單視窗程式示範實務的繼承, 介面實作與監聽器機制介



影片12 用安裝在視窗中的按鈕來控制視窗=>示範內部類別的使用



影片13 用介面轉接類別 (Adapter) 與匿名類別來簡化程式碼


影片14 用開發只有新增與刪除功能的ArrayList 類別來示範 Is-a  Has-a




範例

一、存取限制

1.          package

用來群組相關型別,並提供存取的保護與名稱空間的管理。裡面可以包含類別、介面與 enum

宣告敘述必須是程式碼裡面的第一行。而且只能宣告一次

如果你的程式碼中宣告了多個型別,只有一個是public。而且該型別名稱必須是檔案名稱。

如果沒有宣告package,該檔案會預設為 unname package。一般而言 unname package 只用在小型的或暫時的專案裡面,或者是你開發過程的起點。否則類別或介面,建議要宣告package

                            i.                creating

程式碼中package的宣告。等同於實體磁碟機中的建立資料夾。package的名稱就是資料夾的名稱。用 . 隔開的 package名稱就是資料夾中的子資料夾名稱。而類別或介面的檔案就存在該資料夾中。

                           ii.                naming

package的名稱以全小寫命名

隨著全世界越來越多的程式設計師用Java開發程式。類別或介面的名稱重複的機會就越來越大。包含package的名字也有可能重複。所以為了辨識方便。會建議使用公司的網址反過來寫。例:tw.com.yung.ClassName

包含package名稱的類別名稱,稱之為類別的全名。

2.          類別

                            i.                public / not public

是否接受不同 package 的類別存取。

                           ii.                import

import 敍述必須置於 package 宣告與 class 宣告之間。數量沒有限制。

l   import package

import package 中的所有型別。

l   import class

import 指定型別。

3.          成員

宣告此成員是否接受其它類別存取

                            i.                private

不接受其它類別存取

                           ii.                default / none declare

接受相同 package 中的其它類別存取。

                         iii.                protected

接受任何 package 中的子類別存取。

                         iv.                public

接受任何 package 中的任何類別存取。

4.          static import

import 指定類別中的 static 成員

5.          override

存取限制可以相同或更寬鬆,不能更嚴格

接受存取的範圍可以相同或更大,不能更小。

二、封裝

資訊隱藏確保資料的正確性。物件建立後應該盡可能的不接受修改。

實作的流程為:

1.          設定所有欄位為 private

2.          提供設定物件值的建構方法。

3.          針對欄位的存取需求提供setter / getter

4.          在 setter 中撰寫確保欄位值合法的程式碼。    

開放的對象為:

1. 物件使用者。

2. 類別使用者

3. 子類別使用者。


三、Design Pattern

1.          Factor Method Pattern

2.          Singleton Pattern

3.          Immutable Pattern

4.          Builder Pattern

四、final

final 是相當特殊的關鍵字。可以宣告在所有宣告敘述的前面。無論是變數的宣告、方法的宣告以及類別的宣告。當然宣告在不同宣告敘述,代表不同的功能。

1.          變數

                            i.                區域變數

宣告時不一定要指派,但只能指派一次

                           ii.                物件欄位

若宣告時沒有指派,必須在所有建構方法指派。

參考變數注意:變數不可改變,不代表變數參照的物件的內容不能改變。

2.          方法

宣告為 final 的方法,不接受子類別 Override

3.          類別

宣告為 final 的類別,不接受繼承

五、Is-a VS Has-a

非必要,不要繼承。

子類別繼承父類別,表面上是一種福利。因為子類別不用宣告就可以擁有父類別中的所有成員。

但其實是受限於父類別

父類別宣告為 private 的成員,子類別不能碰;

父類別宣告為 abstract 的成員,子類別一定要 override

父類別宣告為 final 的成員,子類別就一定不能 override

父類別宣告為 public 的成員,子類別想要沒有都不行。

子類別的開發實際上受到相當多的限制。

而且,一旦繼承,便可以套用多型,但多型並不安全。所以非必要不要繼承。改用 Has-a 反而海闊天空。

 

實例演練 1:用開發簡易視窗類別來示範 Is-a Has-a

Is-a

1.      繼承視窗類別。

2.      新增視窗元件。

3.      新增監聽器。(實作界面)

4.      實作界面轉接類別。

Has-a

1.      建立視窗物件欄位。

2.      控制視窗物件。

 

實例演練 2 : 用開發只有新增與刪除功能的ArrayList 類別來示範 Is-a Has-a

Is-a

1.      繼承 ArrayList

2.      Override 不要的方法。

Has-a

1.      建立 ArrayList 物件欄位。

2.      Forward method