類別的繼承-一般關係: 繼承是宣告的類別繼承現存類別的部份或全部的成員資料和方法 , 新增額外的成員資料和方法或覆寫和隱藏繼承類別的方法 繼承與多重繼承-類別架構 類別的繼承-一般關係: 繼承是宣告的類別繼承現存類別的部份或全部的成員資料和方法 , 新增額外的成員資料和方法或覆寫和隱藏繼承類別的方法
類別架構 類別的繼承關係可以建立類別架構 , 在U M L類別關係中 , 繼承是一般關係(Generalization) 例如:類別Car是繼承自類別Vehicle 上圖的Vehicle類別是Car的父類別 , 反之 , Car類別是Vehiclle類別的子類別 , 在U M L類別圖的繼承是使用空心箭頭線來表示兩個類别的一般關係
繼承不只可以多個子類別繼承同一個父類別 , 而且還可以擁有很多層的繼承 上圖的Truck , Car和Mororeycle類別是兄弟類別 , 當然我們可以繼續繼承類別Car , 類別SportsCar和Jeep也是類別Vehicle的子類別 , 不過並不是直接繼承子類別
類別的繼承 父類別Vehicle定義車輛基本資料: class Vehicle { private int engineNo: private string name; private double price; public void setNumber(int no){….} public void setName(String n){….} public void serPrice(double p){….} public void printVehicle(){….} }
宣告類別繼承自存在的類別 UML類別圖: 宣告語法 Class 子類別名稱 extends 父類別名稱 { 子類別可繼承父類別所有成員資料和方法但有一些限制 子類別不能存取父類別宣告成private的成員資料和方法 父類別的建構子不屬於類別的成員所以子類別並不能繼承父類別的建購子 宣告語法 Class 子類別名稱 extends 父類別名稱 { ……./ / 額外的成員資料與方法 } 以car子類別宣告為例: class Car exends Vehicle private int doors; public Car(String name,int no,double price,int doors){…} Public void printCar(){…} (範例:Ch9_1_2)
覆寫和隱藏父類別的方法 如果繼承父類別方法不符合需求,在子類別可以宣告同名,同參數列和傳回值的方法來取代父類別繼承的方法,稱為覆寫 不過物件的副本方法並不能取代宣告成static的類別方法來取帶它,稱為隠藏
在父類別Vehicle擁有1個類別方法和成員方法需要被隱藏和覆寫 Class Vehicle // 父類別 {….. Public static void printType(){….} ….. Public void printVehicle(){….} } Class Car extend Vehicle //子類別 Public static void printType(){…..} //宣告了與父類別同名 …… Public void printVehicle(){…}
在程式碼呼叫Car物件的副本和類別方法時,是呼叫子類別Car的方法,而不是父類別的方法 上述類別架構可以看出在父與子 類別圖擁有同名的類別和成員方法 (範例Ch9_1_3)
隱藏父類別的成員資料 (範例Ch9_1_4) 在子類別可以隱藏父類別成員資料的變數,只需變數的名稱相同,就算變數的資料型態不同也一樣可以隱藏 例如:父類別成員變數engineNo宣告成public的整數型態 class Vehicle //父類別 { public int engineNo; …………. } 子類別Car的成員變數engineNo是private的字串物件,而不再是整數int,原來public的engineNo成員變數被隱藏起來 class car extend Vehicle //子類別 { private String engineNo; ……….. } (範例Ch9_1_4)
使用父類別的建構子 因為子類別並不會繼承父類別的建構子,所以在子類別只能使用super關鍵字呼叫父類別的建構子,同理,在子類別覆寫的方法和隱藏的成員變數,也可以使用super來呼叫和存取 例如:使父類別擁有建構子 Class Vehicle { public static int count; public int engineNo; public String name; public Vehicle(int name, int no){…..} public void printVehicle() {….} }
class Car extendsVehicle 子類別Car的成員變數name和engineNo隱藏父類別的成員變數成為private { private String name; private int engineNo; private int doors; public Car(String name, int no,int doors) super(name, no); ………. } public void printVehicle() ……. super.printVehicle( ); …….. System.out.println(“名稱(父):”+super.name); System.out.println(“引擎號碼(父)” +super.engineNo) 子類別Car的成員變數name和engineNo隱藏父類別的成員變數成為private 在car類別的建構子使用super(name,no)呼叫父類別的建構子,super.name和super.engineNo取得父類別的成員變數 (範例Ch9_1_5)
Java的介面 Java語言並沒有像C++語言支援多重繼承, 不過Java語言提供[介面](interface),可以建立單一物件多型態和提供多重繼承的功能,本章主要說明介面的使用和繼承
介面的基礎 Java的介面(Interface)可以替類別的物件提供共同介面 , 就算類別間 沒有任何關係(有關係也可以) , 一樣可以擁有共同介面 如同網路通訊協定(Protocol)建立不同電腦網路系統間的管道 , 不管是windows或Unix作業系統的電腦 , 只要會說TCP/IP就可以建立連線也就是說介面是定義不同類別間的一致行為,也就是共同的方法 例如:Car和CD類別擁有同名方法getprice( )取得價格 , Java程式可以將共同方法抽出成為介面Iprice , 如果Book類別也需要取得書價 , 就可以直接實作Irrice介面就表示可以取得物件價格 , 這些類別都擁有相同的行為:取得價格
在U M L圖示的介面圖和類別圖相似,只是在類別名稱上方使用<<interface>>指名此為介面: 上圖介面是類別架構的一般關係(繼承) , 只是使用虛線連接Iprice介面和Car類別 , 在介面方法前並不需使用存取修飾子 在類別上方的<<和>>括起的文字稱為型態名別(Stereotype) , 這是一個標籤或符號 , 用來標示物件額外的型態名稱 , 以此例表示是介面資料型態
介面的建立與使用 Java語言的介面和類別一樣都屬於參考的資料型態 , 介面可以定義類別的行為 , 內含常數和方法的宣告 , 但是並沒有實作的程式碼 , 當類別實作介面時 , 類別需要實作“所有”的介面方法
介面宣告 Java語言的介面可以宣告常數和方法 , 方法屬於抽像方法(Abstract Method)表示只有宣告 , 沒有程式碼 語法: public interface 介面名稱 { final 資料型態 常數=值; …………. 傳回值型態 介面方法( 參數列 ); } 上面的介面宣告使用interface關鍵字 , 類似類別架構 , 只是宣告的內容只有常數和抽象方法(表示尚未實作) 例如:IArea介面 interface IArea { final double PI=3.1415 Void area( ); }
類別實作介面 範例: Circle類別實作IArea介面 class Circle implements IArea { ……. 類別可以實作介面 , 建立介面方法的程式碼 class 類別名稱 implements 介面名稱1,介面名稱2 { …….. // 實作的介面方法 } 上面的類別需要使用implements關建字實作介面 , 如果實作的介面不只一個要用 , 逗號分開 範例: Circle類別實作IArea介面 class Circle implements IArea { ……. public void area( ) System.out.println(“圓面積:”+PI*r*r); }
Circle 類別實作Iarea介面 , 也就是抽象方法area( ) U M L類別圖: 圖例的Circle類別擁有實作介面的area()方法 , 在介面中的常數是隱含宣告成static , 也就是說 , 如同類別變數一般 , 可以直接使用介面名稱取得其值 (範例Ch9_2_2)
在類別實作多個介面 宣告: interface IArea { final douvle PI=3.1415; void area( ); 在Java語言可以實作多個介面 例如:IArea和Ishow兩個介面 宣告: interface IArea { final douvle PI=3.1415; void area( ); } interface Ishow void show( ); 2個介面各擁有1個介面方法 , 在Circle類別可以同時實作IArea和Ishow兩個介面 宣告: class Circle implements IAres,Ishow { ……. public void area ( ) ….. } public void show( ) ……..
類別需要實作兩個介面的2個方法-area()和show() U M L類別圖: Circle類別擁有實作2個介面的area()和show()方法 (範例Ch9_2_3)
類別架構與介面 在類別架構中可以將各類別的共同方法抽出成為介面 , 然後讓各類別實作此介面 例如:Vehicle類別和Car子類别都擁有print()方法顯示類別的成員資料 , 我們可以將print()方法抽出來成為Iprint介面 U M L圖: 上圖介面是獨立在類別架構之外 , 類別架構的各類別不只可以實作IPrint介面 , 還可以實作其它介面 (範例Ch9_2_4)
介面的繼承 宣告新的介面繼承其它介面的所有常數和方法 例如:繼承IArea介面 interface IShape extends IArea 在Java語言的介面並不能隨便新增方法 , 因為實作介面的類別需要實作所有的介面方法 , 如果需要新增介面的抽象方法 , 可以使用介面繼承方式來擴充介面 語法: Interface 介面名稱 extends 繼承的介面 { …..//額外的常數和方法 } 宣告新的介面繼承其它介面的所有常數和方法 例如:繼承IArea介面 interface IShape extends IArea { Void perimeter(); }
介面IShape是繼承自IArea介面 , 新增perimeter()介面方法 U M L圖: 上圖實作Ishape介面的類別一共需要實作area()和perimeter()兩個方法 (範例Ch9_3)
介面的多重繼承-多重繼承的基礎 C++語言支援多重繼承 , 也就是父類別不只一個 , Java語言並不支援多重繼承但是支援介面的多重繼承 多重繼承是指一個類別能夠繼承多個父類别 上圖的Driven_truck類別是繼承來自2個類別Truck和Driver , 擁有兩個父類別稱為多重繼承
介面的多重繼承 語法: interface 介面的名稱 extends 繼承的介面1 , 繼承的介面2 { …..//額外的常數和方法 } 宣告的介面繼承多個介面 , 各介面要用 , 逗號分隔 範例:Ishape介面繼承自Iarea和Ishow介面 Interface Ishape extends IArea , IShow { Void perimeter( ); }
U M L圖:介面Ishape是繼承自IArea和Ishow介面 , 新增perimeter()方法 Ishape介面繼承自兩個父介面 , 實作Ishape介面一共需要實作area() , perimeter()和show()三個方法 (範例Ch9_4_2)
習題 9_10 U M L圖: 9_12 U M L圖: