Ch07 介面與多重繼承 物件導向程式設計(II)
單一繼承 vs 多重繼承(1/2) Java的繼承是屬於單一繼承,C++的繼承是屬於多重繼承 多重繼承是指:指一個類別能夠繼承多個父類別 在許多時候多重繼承的性質是相當有用。 在Java,多重繼承的性質交給介面。
單一繼承 vs 多重繼承(2/2) 多重繼承的性質很有用,現實環境中,處處是多重繼承,想想以下情境: 你有一隻手機,它有PDA和GPS的功能,有一天,ToTo跟你借GPS 如果1:你怕ToTo弄壞了,他的媽媽又不會賠,這時,你可以採用『單一繼承』的說法, “不好意思,我有行動電話” 如果2:你不怕ToTo弄壞,因為他弄壞了,你就可以順理成章的成為他的小童星經紀人,好好利用他大賺一筆;則,你可以採用『多重繼承』的說法, “我有一隻手機,它有GPS的功能,借給你”
動動小手時間(1) 請繪出上一頁的行動電話的繼承圖
介面(1/2) 介面中定義的方法就像是飲料販賣機上的按鈕
介面(2/2) 介面(Interface)是在類別繼承架構中定義類別行為,內含常數和方法宣告,但是並沒有實作程式碼
介面的定義與實作(1/3) 定義介面的語法: 介面定義的例子: 修飾字 interface 介面名稱 { //靜態常數定義 //抽象方法宣告 } 介面定義的例子: interface MyInterface int i=2; //已預設使用 public、final、static void m(); //已預設使用 public、abstract
介面的定義與實作(2/3) 實作介面的類別定義語法: 修飾字 class 類別名稱 implements 介面名稱 { //包含實作方法的敘述 }
介面的定義與實作(3/3) 介面多重繼承的語法: 類別實作多個介面的語法: interface 子介面 extends 父介面一, 父介面二, ... { //新增的靜態常數及抽象方法 } 類別實作多個介面的語法: class 類別名稱 implements 介面一, 介面二, ... //類別主體敘述
範例1:宣告與使用介面(1/4) UML類別圖,如下圖所示:
範例1:宣告與使用介面(2/4) AreaInterface介面,如下所示: interface AreaInterface { final double PI = 3.1415926; void area(); }
範例1:宣告與使用介面(3/4) 接著Circle類別可以實作這個介面,如下所示: class Circle extends Shape implements AreaInterface { ……… public void area() { System.out.println("X座標: " + x); System.out.println("Y座標: " + y); System.out.println("圓半徑: " + r); System.out.println("圓面積: " + PI*r*r); }
範例1:宣告與使用介面(4/4) abstract class Shape0601 { public double x; public double y; } interface AreaInterface0601 { final double PI = 3.1415926; void area(); class Circle0601 extends Shape0601 implements AreaInterface0601 { public double r; public Circle0601(double x, double y, double r) { this.x = x; this.y = y; this.r = r; public void area() { System.out.println("X座標: " + x); System.out.println("Y座標: " + y); System.out.println("圓半徑: " + r); System.out.println("圓面積: " + PI*r*r); class Ch06_01 { public static void main(String [] args) { Circle0601 c = new Circle0601(5.0, 5.0, 8.0); c.area(); System.out.println("PI常數: " + AreaInterface0601.PI); System.out.println("PI常數(以物件方式): " + c.PI); }
介面也是物件的型別 當物件所屬之類別在定義時實作某個介面,則此物件也「屬於」該介面型別的物件。意即,介面也是物件的型別。 若某個物件,其所屬之類別沒有實作介面,卻定義了介面宣告的方法時,該物件還是不屬於介面型別。 介面是物件的型別,所以介面也可以為陣列的基底型別,而形成異質集合。
介面的多重繼承 介面和介面之間也可以有繼承的關係,而且可以有多重繼承的關係 不可以有靜態常數的重複繼承。如果不同父介面中定義了同名的常數,則子介面型別的物件不可以使用該常數,以免發生曖昧不明的狀況
範例2:介面的多重繼承(1/3) 實線為繼承(extends),虛線為實作介面(implements)
範例2:介面的多重繼承(2/3) 請先練習一下功力 Ch06_02.java
範例2:介面的多重繼承(3/3) class Ch06_02 { public static void main(String [] args) CCF a = new CCF(); a.m1(); a.m3(); a.m4(); a.m5(); } abstract class CCE String name = "CCE"; abstract void m1(); void m2() System.out.println("我在CCE的m2啦!"); interface IIA String name = "IIA"; void m3(); void m5(); interface IIB String name = "IIB"; interface IIC extends IIA, IIB String name = "IIC"; interface IID String name = "IID"; void m4(); class CCF extends CCE implements IIC, IID { String name = "CCF"; void m1() System.out.println("我在CCF的m1!"); m2(); } public void m3() System.out.println("我在CCF的m3!"); public void m4() System.out.println("我在CCF的m4!"); public void m5() System.out.println("我在CCF的m5!"); }請先練習一下功力
介面vs抽象類別(1/3) 介面和抽象類別的相似之處: 不能直接使用介面或抽象類別建立物件 介面與抽象類別都可以宣告抽象方法。
介面vs抽象類別(2/3) 介面(Interface)是在類別繼承架構中定義類別行為,內含常數和方法宣告,但是並沒有實作程式碼,它和抽象類別的差異,如下所示: 抽象類別的方法可能只有宣告,但是仍然可以擁有一般方法,介面的方法都只有宣告,而且一定沒有實作的程式碼。 介面不屬於類別的繼承架構,就算亳無關係的類別也一樣可以實作同一個介面。 類別只能繼承一個抽象類別,但是可以同時實作多個介面。
介面vs抽象類別(3/3) 介面和抽象類別的相異之處: 介面內的方法皆為 public 和 abstract 方法。抽象類別的抽象方法存取修飾字不限為 public。 介面內的屬性皆預設為public、static及final宣告,必須指定其值。抽象類別中的屬性則沒有限定 介面之間可以有多重繼承。抽象類別和其它類別之間只能有單一繼承 介面的目的是制訂整組訊息接收器的規格,模擬類別的多重繼承。抽象類別的目的則是制訂部份物件的規格,並制訂部份訊息接收器的規格,為多型做準備
大腦、小手動一動(2) 請設計兩種類別: 珍珠奶茶 奶茶珍珠 兩個物件分屬這兩類別