繼承與多重繼承-類別架構

Download Report

Transcript 繼承與多重繼承-類別架構

繼承與多重繼承-類別架構
類別的繼承-一般關係:
繼承是宣告的類別繼承現存類別的部份或全
部的成員資料和方法 , 新增額外的成員資料和
方法或覆寫和隱藏繼承類別的方法
類別架構
類別的繼承關係可以建立類別架構 , 在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 父類別名稱
{
……./ / 額外的成員資料與方法
}
以car子類別宣告為例:
class Car exends Vehicle
{
private int doors;
public Car(String name,int no,double price,int
doors){…}
Public void printCar(){…}
}
(範例:Ch9_1_2)
子類別可繼承父類別所有成員資料和方法但有
一些限制
子類別不能存取父類別宣告成private的成員資
料和方法
父類別的建構子不屬於類別的成員所以子類別
並不能繼承父類別的建購子
覆寫和隱藏父類別的方法
如果繼承父類別方法不符合需求,在子類
別可以宣告同名,同參數列和傳回值的方
法來取代父類別繼承的方法,稱為覆寫
不過物件的副本方法並不能取代宣告成
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)
隱藏父類別的成員資料
在子類別可以隱藏父類別成員資
料的變數,只需變數的名稱相同,
就算變數的資料型態不同也一樣
可以隱藏
例如:父類別成員變數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
{
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( );
}
類別實作介面
類別可以實作介面 , 建立介面方法的
程式碼
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)
在類別實作多個介面
在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)
介面的繼承
在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圖: