收藏 分享(赏)

继承、多型、介面.ppt

上传人:天天快乐 文档编号:1284242 上传时间:2018-06-21 格式:PPT 页数:74 大小:7.91MB
下载 相关 举报
继承、多型、介面.ppt_第1页
第1页 / 共74页
继承、多型、介面.ppt_第2页
第2页 / 共74页
继承、多型、介面.ppt_第3页
第3页 / 共74页
继承、多型、介面.ppt_第4页
第4页 / 共74页
继承、多型、介面.ppt_第5页
第5页 / 共74页
点击查看更多>>
资源描述

1、Visual C# 2010 程式設計經典,第7章繼承、多型、介面,7.1 繼承7.1.1 類別繼承,物件導向程式設計中的繼承就類似真實世界的遺傳一樣,例如兒子會遺傳爸爸或媽媽的特色(屬性或方法),且兒子會再擁有自己新的特色。透過繼承的機制可以讓新的類別可以延伸出更強的功能,通常我們將被繼承的類別稱為基底類別(base class)、父類別(parent class)或超類別(super class),而繼承的類別稱為衍生類別(derived class)、子類別(child class)或次類別(sub class)。當子類別繼承自父類別之後,子類別會擁有父類別所有的成員(屬性、方法、欄位)

2、,C# 的繼承語法如下:,7.1.2 類別成員的存取限制,類別的成員存取修飾詞除了可以使用private和public之外,還可以使用protected,下面我們對這三個常用的修飾詞來加以說明:publicpublic成員的存取沒有限制,可以在類別中、子類別中或宣告的物件中使用public成員。是屬於公用層級。privateprivate成員只能在自身類別內做存取的動作。是屬於私用層級,外界無法使用。protectedprotected成員除了可以讓自身類別存取之外,也可以讓子類別做存取。是屬於保護層級。,下面範例定義Employee員工類別有Salary屬性,Salary屬性薪水設定介於20

3、00040000之間。然後再定義一個繼承自Employee員工類別的Manager經理類別,並在經理類別中新增一個Bonus獎金屬性以及顯示實領薪水的ShowTotal方法。因為Manager經理類別繼承自Employee員工類別,所以Manager類別擁有Employee類別的所有成員(屬性及方法),因此Manager類別也可以使用Salary屬性。完整程式碼如下:,7.2 靜態成員7.2.1 靜態成員的使用,在類別中除了上述private、protected、public三種不同等級的成員宣告方式之外,在某些特殊狀況下還可以使用static敘述來宣告靜態成員(Static Members)

4、。使用static宣告出來的成員是不需要經過new敘述來建立物件實體就可以直接透過類別來使用的。static成員在記憶體中只會儲存一份,且類別所產生的物件都可以一起共用static成員。,例如下面例子,在Car類別中宣告Total靜態屬性用來記錄車子物件的總數,當建立Car物件執行建構式時,Total即馬上加上1;在Car類別定義ShowTotalCars() 靜態方法用來顯示目前共產生幾部車子,呼叫此方法可直接使用Car. ShowTotalCars(); 敘述,不用建立Car物件。完整程式碼如下:,7.2.2 .NET Framework的記憶體配置,7.3 多型,多型又稱同名異式,它是透

5、過動態繫結的方式讓您在程式執行時期可以動態決定物件參考所要執行的方法。多型允許您在程式中使用名稱相同的方法或屬性,但不需考慮當時使用的物件型別是什麼。若要設計多型,子類別就必須先覆寫父類別同名稱的方法或屬性,接著再使用父類別的物件參考來選擇所要執行子類別物件實體的方法。由於多型的使用上會在類別中建立名稱相同的成員(屬性或方法),多載和覆寫也可以建立名稱相同的成員,因此有必要釐清這兩者的概念:,多載成員:可接受不同個數的參數或不同資料型別的參數,用來提供不同版本的屬性或方法。覆寫成員:子類別的成員可用來取代父類別中不適用的成員,子類別覆寫父類別的成員時,子類別與父類別的成員必須接受相同個數的參數

6、與相同的資料型別。,7.3.1 覆寫,如果子類別想要重新定義父類別的方法或屬性(覆寫),首先必須將父類別的方法宣告為virtual,表示父類別允許被子類別同名的方法覆蓋。而子類別要覆蓋父類別同名稱的方法,必須將子類別的方法宣告為override(覆寫),表示要重新定義父類別的方法。,一般來說員工和經理的底薪一定不相同,在Polymorphism-1.sln範例我們將Employee員工類別的Salary屬性宣告為virtual可被覆寫,且員工Salary薪水屬性介於2000040000之間。Manager經理類別的Salary薪水屬性宣告為override來覆寫父類別的Salary屬性,且重新

7、定義Manager經理類別的Salary薪水屬性介於3000060000。完整程式碼如下:,7.3.2 子類別如何存取父類別的 方法或屬性,如果子類別只是要加強父類別方法而己,在子類別方法中並不需要再重新撰寫和父類別方法中相同的程式,只要在子類別的方法中呼叫父類別的方法,然後在子類別方法內加上新的功能即可。在C# 您可以使用base這個關鍵字來呼叫父類別的屬性或方法。寫法如下:,base.方法(引數串例)/呼叫父類別的方法base.屬性/呼叫父類別的屬性,下面例子Employee父類別的ShowTotal方法會顯示底薪,而Manager子類別的ShowTotal方法除了要顯示底薪之外,還必須顯

8、示薪水+獎金的總額。因此在Manager類別ShowTotal方法中只需要使用base.ShowTotal來呼叫Employee的ShowTotal方法,然後再加上要顯示薪水+獎金的程式敘述就可以了。,7.3.3 動態繫結,一般程式編譯階段時,物件參考即會決定自己要執行的方法。動態繫結(Dynamic Binding)是程式執行階段時物件參考才決定所要執行的方法,其做法是使用父類別的物件參考來選擇所要執行子類別物件實體的方法,透過這種技巧才可以做到真正的多型。,下面這個範例我們模擬使用者可以選擇駕駛車子及飛機共前進幾公里。範例中Traffic交通工具類別中包含_miles共用成員用來記錄已前進

9、的公里數,且還有一個空的SpeedUp加速方法,子類別Car和Airplane類別分別繼承了Traffic(車子和飛機都是交通工具)且覆寫了Traffic父類別SpeedUp方法,Car類別的SpeedUp方法每一次加速是前進2公里;Airplane類別的SpeedUp方法每一次加速是前進15公里。在Main() 方法中設定一個無窮迴圈讓使用者選擇要駕駛車子或飛機。若按 “1” 選擇車子即將Traffic的參考物件r指向Car的myCar物件實體,此時執行r.SpeedUp()即會呼叫Car類別的SpeedUp方法。若按 2 選擇飛機即將Traffic的參考物件r指向Airplane的myAi

10、rplane物件實體,此時執行r.SpeedUp()會呼叫Airplane的SpeedUp方法。,7.3.4 抽象類別,抽象類別可定義抽象方法或存取子,最常應用的地方就是抽象類別中的某些功能可以繼承給子類別(衍生類別),然後再由子類別對所繼承的抽象類別中的抽象方法或存取子進行實作,若要宣告抽象類別、抽象方法可以使用abstract 修飾詞。若使用 abstract 修飾詞宣告方法或屬性,即表示此方法或屬性並沒有包含實作的部分。例如:以下敘述的Answer方法沒有程式主體,只有方法宣告及( )和;結束而己。 public abstract void Answer();使用abstract來定義抽

11、象類別及抽象方法,而抽象方法不包含實作程式碼,因此必須在繼承的子類別中以override(覆寫)修飾詞定義新的方法功能。,多型-範例一建立一個Windows Form應用程式專案Polymorphism-4,並且將所有的類別定義全部放在Class1.cs類別檔中,操作步驟如下:,這個範例的製作原理如下:如果要利用多型的特性來做,勢必要宣告出一個物件變數的參考(Reference),然後在各個控制項的Click事件中再動態繫結到對應的控制項變數去,然後再來將Left屬性加上10就可以了,問題是這些控制項都繼承自哪個類別呢?沒錯!所有 .NET Framework中的控制項都繼承自Control類

12、別,所以我們可以宣告一個Control類別的物件變數參考(Reference),變數名稱為objToMove,其寫法如下: Control objToMove;,7.4 介面與實作,而介面是物件的某些操作集合。例如汽車可以有駕駛的介面 (左轉、右轉、加速、減速),對於駕駛人來說,只要任何交通工具具有駕駛的介面,就可以駕駛它 (多型),但是對於加油站的加油員來說,只要任何交通工具有加油的介面 (開油箱蓋、加油、關油箱蓋),他都可以為它加油 (多型),因此汽車由於具有加油的介面,所以到加油站去加油員可以為它加油。因此介面的使用焦點是放在操作物件這件事上,而類別繼承則是將焦點放在屬性與方法的重覆使用

13、這件事上。參考http:/.tw/post/224/805,一. 如何使用介面,介面和類別很像,類別可以定義屬性、方法和事件,但介面和類別不同的是,介面只宣告方法、屬性和事件成員,且介面所宣告的成員皆會自動成為public公用成員。介面最主要是用來宣告一組可操作的方法,它就代表一種方法的合約,當類別實作(Implements)某介面之後,該介面所宣告的方法要在類別重新實作過。例如Car本身擁有SpeedUp方法,現在想再加上Fly方法,首先可以使用interface關鍵字定義IFly介面,該介面內宣告Fly方法,其寫法如下:,interface IFly / 定義IFly介面 void Fly

14、(int n);/ 宣告Fly方法 ,接著在Car類別就可以使用:符號來指定要實作IFly介面,並為Car類別加上Fly() 方法。其寫法如下:,class Car : IFly /Car類別實作IFly介面 public void SpeedUp(int n) Console.WriteLine(車子加速前進 0 公里, n); /Car類別的Fly方法實作IFly介面的Fly方法 public void Fly(int n) Console.WriteLine(車子飛上天前進 0 公里, n); ,下面InterfaceDemo.sln範例,在Car類別具有SpeedUp() 加速方法,B

15、ird類別具有Eat() 吃的方法,若希望Car類別和Bird類別同時擁有Fly() 飛的方法,在這裡定義IFly介面內宣告Fly() 方法,一旦Car類別和Bird類別實作IFly介面的Fly() 方法,此時Car類別和Bird類別的物件即可以呼叫Fly() 方法。,Array類別中有一個Sort方法,可以用來排序一維陣列的資料,例如排序一個整數陣列:但是如果想要排序非內建型別 (int, long ) 的陣列,Sort方法就不支援了,這時候該怎麼辦呢?,int Scores = new int 89, 65, 31, 89, 92, 46 ;Array.Sort(Scores);,在Arr

16、ay類別中引用了一個IComparable的介面 (介面的名稱前面一般都以一個大寫的I來表示),在這個介面中定義了一個CompareTo的方法,用來比較物件的大小:CompareTo方法的規則是:如果引用IComparable介面的物件比obj參數小,則傳回一個負數;如果相等則傳回0;如果大於obj參數,則傳回一個正數。,interface IComparable int CompareTo(Object obj) ;,在Array.Sort方法中進行排序動作時,會呼叫CompareTo這個方法來比較陣列中兩個元素的大小。因此,只要我們實作出CompareTo這個方法來讓Array.Sort方

17、法呼叫,那麼就可以排序自定型別的資料了。在以下的這個範例中,為了達到上述的目的,我們定義了一個Vector的類別,並且在類別宣告時指名在這個類別中要實作出IComparable介面:,class Vector : IComparable,然後在類別中定義CompareTo方法,並且指明這個方法就是用來實作出IComparable介面中的CompareTo方法的實體:,int IComparable.CompareTo(object obj) Vector v = (Vector) obj; return (X * X + Y * Y) - (v.X * v.X + v.Y * v.Y);,也就

18、是說,經上面兩個步驟的處理,就可以讓我們的Vector類別變成一個可以支援IComparable介面的類別,也就是說這樣就可以讓Array.Sort方法在進行排序的時候,呼叫Vector陣列 (vecArray) 中每一個Vector物件中的CompareTo方法來進行排序:,Array.Sort(vecArray);,三. 如何使用介面 模擬System.Array類別,上一個範例中,我們僅僅了解執行Array.Sort(vecArray)時,Sort方法可以呼叫vecArray陣列中每一個元素的CompareTo方法來進行元素大小比較,然後進行排序,然而在Sort方法中究竟是如何做的呢?為

19、了再深入了解介面的定義方式,我們就來模擬System.Array物件中有關Sort方法的技術。,在下面的程式碼中,定義了一個IMyComparable介面,這個介面中僅有一個方法(函式)MyCompareTo,方法的規格和IComparable介面的CompareTo方法一模一樣,另外也比照Array類別定義了一個MyArray類別,這個類別中只有一個Shared方法MySort,在MySort中使用最簡單的汽泡排序法來針對參數obj陣列進行排序,在比較陣列元素大小時,就直接呼叫MyCompareTo方法來做比較,因此要做為MySort方法參數的obj物件 (Vector類別) 一定要事先實作

20、出IMyComparable介面的MyCompareTo方法才可以。,7.5 delegate委派型別,委派是用來儲存方法位址的資料型別。資料型別可以用來宣告變數或物件,例如 int 型別宣告出來的變數可以儲存數字、string型別宣告出來的變數可以儲存文字。委派也是一種資料型別,只是這種資料型別宣告出來變數所儲存的是方法的位址,一個儲存了方法位址的委派變數,可以用來呼叫該位址的方法,由於變數的內容可以動態改變,因此只要將該變數內容改變為另一個方法的位址,該變數呼叫的就會是另一個方法。在定義物件的事件時,由於無法預期未來使用這個物件事件的事件處理函式(即方法)的位址,因此在物件中就必須使用委派

21、來宣告事件變數,以便可以動態的將事件變數指向事件處理函式,物件就可以動態使用事件的變數來呼叫外部的事件處理函式。,因此方法(函式)也可以當做一種型別,例如在陣列排序的例子中,如果我們希望MySort方法排序的方式可以由大排到小,也可以由小排到大,因此在MySort方法中多加一個參數CompareMethod,指明比較陣列元素大小的方法,由於CompareMethod參數的型別是一種方法(函式),這時候就可以使用delegate來定義方法的型別 (參數個數、參數順序、傳回值型別),首先必須先使用delegate敘述定義出方法的格式與型別名稱CompareFunc:,delegate bool C

22、ompareFunc(int X, int Y);,將來這個CompareFunc就可以當成型別來做參數或變數宣告,例如:這樣MySort中就可以直接呼叫傳進來的CompareMethod方法來進行陣列元素大小的比較:,static void MySort(int obj, CompareFunc CompareMethod),if (CompareMethod(objj, obji) ,這種型別的變數其實就是指向函式或方法的位址,例如可以用以下程式來取得IsSmaller方法的位址:也就是說經過上述程式取得IsSmaller方法的位址之後,下面這兩行指令其實都是呼叫IsSmaller方法:,

23、CompareFunc CompareIt;CompareIt = new CompareFunc(IsSmaller);,if (IsSmaller(15, 20) if (CompareIt(15, 20) ,7.6 視窗應用程式,在第五章使用Windows Form應用程式專案並透過拖拉的方式來建立表單及控制項的配置與事件處理函式,在本節將介紹使用主控台應用程式來建立Windows Form應用程式。在 .NET Framework的類別程式庫是以類別繼承架構而來,因此我們可以自行設計一個類別,然後繼承自System.Windows.Forms.Form類別,該類別即擁有表單的屬性及方法,接著您再自行延伸所要的功能即可。,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 经营企划

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报