• 沒有找到結果。

11.1 抽象類別

N/A
N/A
Protected

Academic year: 2021

Share "11.1 抽象類別 "

Copied!
31
0
0

加載中.... (立即查看全文)

全文

(1)

第 第 十 十 一 一 章 章

抽 抽 象 象 類 類 別 別 與 與 介 介 面 面

本章學習目標

認識抽象類別 學習介面的使用

認識多重繼承與介面的延伸

(2)

11.1 抽象類別

抽象類別的目的是要依據它的格式來修改並建立新的類別。

11.1.1 定義抽象類別 定義抽象類別的語法如下:

abstract class 類別名稱 // 定義抽象類別 {

宣告資料成員;

傳回值的資料型態 method 名稱(引數...) {

...

}

修飾子 abstract 傳回值資料型態 method 名稱(引數...);

}

定義一般method

定義抽象method。注 意於抽象method 裡,

沒有定義處理的方式 格式11.1.1

抽象類別的定義格式

(3)

11.1.2 抽象類別的實作

例如,想設計一個父類別 CShape,依據此類別可用來衍生出圓形、長 方形與三角形等幾何形狀的類別:

CShape 類別 CShape 類別

CRectangle類別

CRectangle類別 CCircle類別CCircle類別

CTriangle 類別 CTriangle

類別 父類別

子類別

(4)

下面的父類別程式碼,即是抽象類別 CShape 的內容:

01 // 定義抽象類別 CShape

02 abstract class CShape // 定義抽象類別 CShape 03 {

04 protected String color; // 資料成員

05 public void setColor(String str) // 一般 method,用來設定何形狀的顏色 06 {

07 color=str;

08 }

09 public abstract void show(); // 抽象函數,在此沒有定義處理方式 10 }

(5)

下面的程式碼是以子類別 CCircle 為例來撰寫的:

01 // 定義由抽象類別 CShape 而衍生出的子類別 CCircle 02 class CCircle extends CShape //定義子類別 CCircle 03 {

04 protected double radius; // 資料成員 05 public CCircle(double r) // 建構元 06 {

07 radius=r;

08 }

09 public void show() 10 {

11 System.out.print("color="+color+", ");

12 System.out.println("area="+3.14*radius*radius);

13 } 14 }

在此處明確定義 show()的處理方式

(6)

app11_1 是抽象類別實作的完整範例。

01 // app11_1, 抽象類別的實例

02 abstract class CShape // 定義抽象類別 CShape 03 {

04 protected String color; // 資料成員 05 public void setColor(String str) // 一般的函數 06 {

07 color=str;

08 }

09 public abstract void show(); // 抽象函數,只有宣告,但沒有定義處理方式 10 }

11 class CRectangle extends CShape // 定義子類別 CRectangle 12 {

13 protected int width,height;

14 public CRectangle(int w,int h) 15 {

16 width=w;

17 height=h;

18 }

19 public void show() // 明確定義繼承自抽象類別的 Show() method 20 {

21 System.out.print("color="+color+", ");

22 System.out.println("area="+width*height);

23 } 24 }

(7)

25 class CCircle extends CShape // 定義子類別 CCircle 26 {

27 protected double radius;

28 public CCircle(double r) 29 {

30 radius=r;

31 }

32 public void show() // 明確定義繼承自抽象類別的 Show() method 33 {

34 System.out.print("color="+color+", ");

35 System.out.println("area="+3.14*radius*radius);

36 } 37 }

38 public class app11_1 39 {

40 public static void main(String args[]) 41 {

42 CRectangle rect=new CRectangle(5,10);

43 rect.setColor("Yellow");

44 rect.show();

45

46 CCircle cir=new CCircle(2.0);

47 cir.setColor("Green");

48 cir.show();

49 } 50 }

/* app11_1 OUTPUT--- color=Yellow, area=50 color=Green, area=12.56 ---*/

(8)

CShape、CCircle 與 CRectangle 的 show() method 之間的關係圖:

abstract class CShape { ...

abstract void show();

}

CShape 類別

public void show() {

// 明確定義 show()的內容 }

CRectangle 類別

public void show() {

// 明確定義 show()的內容 }

CShape 類別

show() method 宣告成 abstract (只有宣告,沒有明確定義)

(9)

11.1.3 用抽象類別型態的變數來建立物件

利用父類別的變數來存取子類別物件的成員

app11_2 是以抽象類別型態的變數建立物件的範例:

01 // app11_2, 用抽象類別型態的變數來建立物件 02 // 將 app11_1 的 CShape 類別的定義放在這兒 03 // 將 app11_1 的 CRectangle 類別的定義放在這兒 04 // 將 app11_1 的 CCircle 類別的定義放在這兒 05 public class app11_2

06 {

07 public static void main(String args[]) 08 {

09 CShape shape1=new CRectangle(5,10);

10 shape1.setColor("Yellow");

11 shape1.show();

12

13 CShape shape2=new CCircle(2.0);

14 shape2.setColor("Green");

15 shape2.show();

16 } 17 }

以類別CShape 建立物件 shape1,並以它來存取子 類別CRectangle 的成員

以類別CShape 建立物件 shape2,並以它來存取子 類別CCircle 的成員

/* app11_2 OUTPUT--- color=Yellow, area=50 color=Green, area=12.56 ---*/

(10)

利用父類別的陣列變數來存取子類別物件的成員

當所建立的物件較多時,可利用父類別的陣列變數來存取子類別物件的 成員:

(1) 先建立父類別的陣列變數

(2) 利用陣列元素建立子類別的物件,並以它來存取子類別的內容

(11)

app11_3 改寫了 app11_2:

01 // app11_3, 利用父類別的陣列變數來存取子類別的內容 02 // 將 app11_1 的 CShape 類別的定義放在這兒

03 // 將 app11_1 的 CRectangle 類別的定義放在這兒 04 // 將 app11_1 的 CCircle 類別的定義放在這兒 05 public class app11_3

06 {

07 public static void main(String args[]) 08 {

09 CShape shape[]; // 宣告 CShape 型態的陣列變數

10 shape=new CShape[2]; // 產生兩個 CShape 抽象類別型態的變數 11

12 shape[0]=new CRectangle(5,10);

13 shape[0].setColor("Yellow");

14 shape[0].show();

15

16 shape[1]=new CCircle(2.0);

17 shape[1].setColor("Green");

18 shape[1].show();

19 } 20 }

利用陣列變數 shape[0]

建立物件,並存取子類別 的成員

利用陣列變數 shape[1]

建立物件,並存取子類別 的成員

/* app11_3 OUTPUT--- color=Yellow, area=50 color=Green, area=12.56 ---*/

(12)

11.1.4 使用抽象類別的注意事項

9 抽象類別不能用來直接產生物件。

9 在抽象類別內可以定義建構元,以供子類別的建構元呼叫。

9 定義在抽象類別裡的抽象函數,在子類別裡一定要被「改寫」。

9 如果子類別裡沒有「改寫」抽象函數,則子類別也要宣告成

abstract。

(13)

11.2 介面的使用

介面與抽象類別有下列兩點不同:

(1) 介面的資料成員必須初始化(即設定初值)。

(2) 介面裡的 method 必須全部都宣告成 abstract。

(14)

介面定義的語法如下:

interface 介面名稱 // 定義介面 {

final 資料型態 成員名稱=常數; // 資料成員必須設定初值

修飾子 abstract 傳回值資料型態 method 名稱(引數...);

}

宣告抽象method。注 意於抽象method 裡,

沒有定義處理的方式 格式11.2.1 介面的定義格式

(15)

下面的範例定義一介面 iShape2D:

01 // 定義 iShape2D 介面 02 interface iShape2D 03 {

04 final double pi=3.14; // 資料成員一定要初值化

05 abstract void area(); // 抽象函數,不需要定義處理方式 06 }

程式碼可改寫如下:

01 // 定義 iShape2D 介面,省略 final 與 abstract 關鍵字 02 interface iShape2D

03 {

04 double pi=3.14; // 省略 final 關鍵字 05 void area(); // 省略 abstract 關鍵字 06 }

(16)

利用介面 A 打造新的類別 B 的過程,稱之為以類別 B 實作介面 A,或 簡稱介面的實作(implementation)。

介面實作的語法:

class 類別名稱 implements 介面名稱 // 介面的實作 {

... ...

}

格式11.2.2 以類別實作介面 的語法

(17)

下面是以 CCircle 類別實作 iShape2D 介面的範例:

01 // 介面的實作

02 class CCircle implements iShape2D // 以 CCircle 類別實作 iShape2D 介面 03 {

04 double radius;

05 public CCircle(double r) // 建構元 06 {

07 radius=r;

08 }

09 public void area() // 定義 area()的處理方式 10 {

11 System.out.println("area="+pi*radius*radius);

12 } 13 }

以類別 CCircle 來實作 介面iShape2D

(18)

app11_4 是以 iShape2D 介面實作 CCircle 與 CRectangle 二個類別的 範例:

01 // app11_4, 介面的實作範例

02 interface iShape2D // 定義介面 03 {

04 final double pi=3.14;

05 abstract void area();

06 } 07

08 class CRectangle implements iShape2D// 以CRectangle 類別實作 iShape2D 介面 09 {

10 int width,height;

11 public CRectangle(int w,int h) 12 {

13 width=w;

14 height=h;

15 }

16 public void area() // 定義 area()的處理方式 17 {

18 System.out.println("area="+width*height);

19 } 20 } 21

22 class CCircle implements iShape2D// 以 CCircle 類別實作 iShape2D 介面

(19)

23 {

24 double radius;

25 public CCircle(double r) 26 {

27 radius=r;

28 }

29 public void area() // 定義 area()的處理方式 30 {

31 System.out.println("area="+pi*radius*radius);

32 } 33 } 34

35 public class app11_4 36 {

37 public static void main(String args[]) 38 {

39 CRectangle rect=new CRectangle(5,10);

40 rect.area(); // 呼叫 CRectangle 類別裡的 area() method 41

42 CCircle cir=new CCircle(2.0);

43 cir.area(); // 呼叫 CCircle 類別裡的 area() method 44 }

45 } /* app11_4 OUTPUT---

area=50 area=12.56

---*/

(20)

app11_5 是利用透過介面型態的變數來存取物件的範例。

01 // app11_5,透過介面型態的變數來存取物件 02 // 將 app11_4 的 iShape 介面的定義放在這兒 03 // 將 app11_4 的 CRectangle 類別的定義放在這兒 04 // 將 app11_4 的 CCircle 類別的定義放在這兒 05 public class app11_5

06 {

07 public static void main(String args[]) 08 {

09 iShape2D var1,var2; // 宣告介面型態的變數

10 var1=new CRectangle(5,10); // 將介面型態的變數 var1 指向新建的物件 11 var1.area(); // 透過介 var1 呼叫 show() method 12

13 var2=new CCircle(2.0); // 將介面型態的變數 var2 指向新建的物件 14 var2.area(); // 透過介面 var2 呼叫 show() method 15 }

16 }

/* app11_5 OUTPUT-- area=50

area=12.56

---*/

(21)

11.3 多重繼承

Java 並不允許多個父類別的繼承:

用類別來實作兩個以上的介面,即可實現多重繼承。

子類別子類別 父類別1

父類別1 父類別父類別22 父類別父類別33

(22)

將類別和兩個以上的介面實作在一起的語法如下:

class 類別名稱 implements 介面 1,介面 2,...

{

... ...

}

格式11.3.1 實作兩個以上的介面

(23)

app11_6 是以兩個介面 iShape2D 和 iColor 來實作 CCirlce 類別的範例。

01 // app11_6, 用 CCircle 類別實作兩個以上的介面 02 interface iShape2D // 定義 iShape2D 介面 03 {

04 final double pi=3.14;

05 abstract void area();

06 } 07

08 interface iColor // 定義 iColor 介面 09 {

10 abstract void setColor(String str);

11 } 12

13 class CCircle implements iShape2D,iColor // 實作 iShape2D 與 iColor 介面 14 {

15 double radius;

16 String color;

17 public CCircle(double r) 18 {

19 radius=r;

20 }

21 public void setColor(String str) // 定義 iColor 介面裡的 setColor()

(24)

22 {

23 color=str;

24 System.out.println("color="+color);

25 }

26 public void area() // 定義 iShape2D 介面裡的 area() method 27 {

28 System.out.println("area="+pi*radius*radius);

29 } 30 }

31 public class app11_6 32 {

33 public static void main(String args[]) 34 {

35 CCircle cir;

36 cir=new CCircle(2.0);

37 cir.setColor("Blue"); // 呼叫setColor() method 38 cir.area(); // 呼叫 show() method 39 }

40 }

/* app11_6 OUTPUT--- color=Blue

area=12.56

---*/

(25)

透過類別與介面的實作,可達到多重繼承的目的,如下圖所示:

CCircle類別 CCircle類別 iShape2D介面

iShape2D介面 iColor介面iColor介面

CCircle 類 別 實 作 了 iShape2D 與 iColor 介面

(26)

11.4 介面的延伸

9 介面可透過繼承的技術來衍生出新的介面。

9 原來的介面稱為基底介面(base interface)或父介面(super interface)。

9 衍生出的介面稱為衍生介面(derived interface)或子介面(sub

interface)。

(27)

iShape2D介面 iShape2D介面

iShape介面 iShape介面

iShape3D介面 iShape3D介面

CCircle類別

CCircle類別 CRectangle類別CRectangle類別 CBox類別CBox類別 CSphere類別CSphere類別 父介面

子介面

類別 extends

implements

下圖中的 iShape 是父介面,透過關鍵字 extends 衍生出 iShape2D 與

iShape3D 子介面:

(28)

介面延伸的語法:

interface 子介面名稱 extends 父介面名稱 1, 父介面名稱 2,...

{

... ...

}

格式11.4.1 介面延伸的語法

(29)

下面是介面延伸的範例:

01 // app11_7, 介面的延伸

02 interface iShape // 定義 iShape 介面 03 {

04 final double pi=3.14;

05 abstract void setColor(String str);

06 } 07

08 interface iShape2D extends iShape // 定義 iShape2D 介面, 繼承自 iShape 09 {

10 abstract void area();

11 } 12

13 class CCircle implements iShape2D // 實作 iShape2D 介面 14 {

15 double radius;

16 String color;

17

18 public CCircle(double r) 19 {

20 radius=r;

21 }

22 public void setColor(String str) // 定義 iShape 介面的 setColor() 23 {

(30)

24 color=str;

25 System.out.println("color="+color);

26 }

27 public void area() // 定義 iShape2D 介面裡的 area() 28 {

29 System.out.println("area="+pi*radius*radius);

30 } 31 }

32 public class app11_7 33 {

34 public static void main(String args[]) 35 {

36 CCircle cir;

37 cir=new CCircle(2.0);

38 cir.setColor("Blue"); // 呼叫setColor() method 39 cir.area(); // 呼叫area() method 40 }

41 }

/* app11_7 OUTPUT-- color=Blue

area=12.56

---*/

(31)

參考文獻

相關文件

題目類型

1.提高接收資料的速度 2.降低資料傳輸速度 接收端RX接收資料的速度低於發.

interface ITextBox : IControl// 繼承了介面 Icontrol 的方法 Paint() { void SetText(string text); }. interface IListBox : IControl// 繼承了介面 Icontrol 的方法 Paint() {

以下 Java 程式執行完後,輸出結果為何?(A)無法編譯,因為 Rectangle 類別不能同時 extends 一個類別且 implemets 一個介面(B)無法編譯,因為 Shapes 類別沒有

關於這個課題,以孫昌武《佛教與中國文學》裡的介紹最為全面。 [註 3]

(2) 「唯以分別安立」 ,表示對對象觀察透過分別心找出「性質」 「定

Visual Basic提供了許多控制項介面來處理由鍵盤輸入

Ctrl+N 建立一個新的 VI Ctrl+B 將程式方塊圖中所有壞線移除 Ctrl+R 執行目前的的 VI Ctrl+T 將人機介面與程式方塊圖左右並列 Ctrl+W 關閉目前的的 VI Ctrl+E