接口 接口定義對(duì)象成員的合同,,是現(xiàn)代組件編程不可缺少的一環(huán),。C#采用關(guān)鍵字“interface”來(lái)創(chuàng)建接口,。接口作為一種類型,,它也具有其他類型所共有的五種存取修飾和new重定義修飾符,。接口可以包含方法,、屬性,、事件,、索引器四種成員,,接口本身只能聲明這些成員,,不必也不能提供這些成員的具體實(shí)現(xiàn),。C#不允許為接口成員做任何存取修飾,,接口成員的存取修飾缺省為public——接口本來(lái)就是為其他類型定義的一種成員合同,,對(duì)它們進(jìn)行存取限制不符合應(yīng)用接口的初衷,。同樣的道理,,C#也不允許對(duì)接口做abstract,、virtual,、override,、static修飾,。下面是接口類型聲明的一個(gè)典型的例子: public delegate void StringListEvent(IStringList sender); public interface IstringList { void Add(string s);//方法 int Count { get; }//只讀屬性 event StringListEvent Changed;//事件 string this[int index] { get; set; }//索引器 } 注意這里將接口名稱寫(xiě)成IStringList,其中的大寫(xiě)字母“I”僅僅是.NET平臺(tái)的命名約定,,而非必須,。 接口作為一種用于“合同”的類型不可以像類那樣實(shí)例化,,說(shuō)一個(gè)數(shù)據(jù)是某個(gè)接口類型,,是指該類型實(shí)現(xiàn)了某個(gè)接口,。C#中類或結(jié)構(gòu)可以實(shí)現(xiàn)多個(gè)接口,,實(shí)現(xiàn)了接口的類型必須提供相應(yīng)接口成員的實(shí)現(xiàn)。 interface Icloneable { object Clone(); } class ListEntry: Icloneable { public object Clone() {……} // ICloneable接口實(shí)現(xiàn) } 接口之間可以繼承,,一個(gè)接口可以繼承自多個(gè)接口,。直接或間接繼承自己會(huì)引起編譯時(shí)錯(cuò)誤。下面是一個(gè)接口繼承的例子: interface Icontrol { void Paint(); } interface ITextBox: Icontrol { void SetText(string text); } interface IListBox: Icontrol { void SetItems(string[] items); } interface IComboBox: ITextBox, IListBox {} 通過(guò)繼承,,接口IComboBox擁有Paint,、SetText、SetItems三個(gè)方法合同,。多接口繼承可能會(huì)帶來(lái)同名成員沖突的問(wèn)題,,C#通過(guò)強(qiáng)制轉(zhuǎn)型來(lái)解決這個(gè)問(wèn)題??聪旅娴睦樱? interface Ilist { int Count { get; set; } } interface Icounter { void Count(int i); } interface IListCounter: IList, ICounter {} class C { void Test(IListCounter x) { x.Count(1); // 錯(cuò)誤,!命名沖突 x.Count = 1; // 錯(cuò)誤!命名沖突 ((IList)x).Count = 1; //正確,!調(diào)用IList.Count.set ((ICounter)x).Count(1); //正確,!調(diào)用ICounter.Count } } 注意這種強(qiáng)制轉(zhuǎn)型是在編譯時(shí)進(jìn)行的,并不會(huì)增加程序運(yùn)行的負(fù)擔(dān),。上面的例子用IListCounter接口作為方法Test的參數(shù)類型,,但接口是不可以實(shí)例化的類型,,該怎樣傳遞這樣的參數(shù)呢?答案是傳遞直接或間接實(shí)現(xiàn)了該接口的類或結(jié)構(gòu)的對(duì)象實(shí)例,。 繼承 繼承是面向?qū)ο蟮娜筇卣髦唬韮蓚€(gè)是封裝和多態(tài)),在組件編程中有比較多的應(yīng)用,。C#提供兩種繼承機(jī)制——類繼承和接口繼承。類繼承只允許每個(gè)類有一個(gè)父類(即單繼承),,而接口繼承卻允許一個(gè)類或接口可以同時(shí)繼承(又稱實(shí)現(xiàn))多個(gè)接口。類不可以被接口繼承,。 在C#中類繼承是指通過(guò)繼承子類將擁有除父類的實(shí)例構(gòu)造器、靜態(tài)構(gòu)造器和析構(gòu)器以外的所有成員,。注意這里的“擁有”和“可見(jiàn)性”是不同的,。擁有某個(gè)成員是指該成員確確實(shí)實(shí)地存在于該類中,,但如果該成員的保護(hù)級(jí)不允許該成員在繼承子類中可見(jiàn)(比如private,internal),,我們將不能在子類中對(duì)它們進(jìn)行操作——但這不表示它們不存在,。下面的例子清晰地說(shuō)明了這一點(diǎn): class A{ int count; public int Count { get {return count;} set {count=value; } } } class B:A {} class Test { public static void Main() { B b=new B(); b.Count=39; System.Console.WriteLine(b.Count); } } count變量在A中為private,,在B中不可見(jiàn),,但通過(guò)公有屬性Count的存取,可以清晰地感覺(jué)到它的存在,。 子類在繼承的同時(shí)可以添加新的類成員。new關(guān)鍵字可以使子類在繼承的時(shí)候屏蔽同名的父類成員,,注意這里屏蔽的意思同樣是“不可見(jiàn)”,而非“去除”,。 可以用類修飾關(guān)鍵字abstract和sealed來(lái)控制類繼承時(shí)的行為,。abstract使得該類只能被子類繼承,,而不能被實(shí)例化。sealed不允許該類被繼承,,使得繼承樹(shù)“到此為止”,。 接口繼承由于所有的成員都為public,,它的行為比較簡(jiǎn)單,,僅僅是繼承所有接口的成員,。和類繼承相同的地方是new關(guān)鍵字同樣可以屏蔽同名成員。 多態(tài) 多態(tài)是指為同名方法提供不同實(shí)現(xiàn)的能力,,它使得我們不用關(guān)心方法的具體實(shí)現(xiàn)而僅僅依靠其名稱來(lái)進(jìn)行調(diào)用操作,。比如現(xiàn)在有一個(gè)Road類需要調(diào)用Drive方法,,不管有什么樣的車:Bike,Car或者Jeep,,盡管它們的Drive方式不同,,但只要它們有Drive方法,, Road就可以調(diào)用它們的Drive方法使它們“行駛”,。多態(tài)集中體現(xiàn)了對(duì)象世界的共同行為,,C#提供了三種多態(tài)能力:接口多態(tài)、繼承多態(tài)和抽象多態(tài),。 接口定義一個(gè)類型需要實(shí)現(xiàn)的方法,、屬性,、索引和事件,包括可能的參數(shù)類型和返回值類型,,而把具體的實(shí)現(xiàn)交由相應(yīng)的類或結(jié)構(gòu)來(lái)做,,從而為組件提供多態(tài)能力,。接口多態(tài)不僅為組件提供一個(gè)更好的邏輯功能的聚合方式,,也為組件的多版本提供了很好的支持,。隨著組件規(guī)模的不斷增長(zhǎng),,需要的成員越來(lái)越多,,將所有的成員簡(jiǎn)單地封裝在一個(gè)組件內(nèi)不符合邏輯思維方式,,更會(huì)帶來(lái)版本問(wèn)題,。而將這些成員分解成多個(gè)聚合的邏輯塊,,然后采用接口的形式將它們進(jìn)行封裝,這種方式很好地解決了組件在設(shè)計(jì)和維護(hù)兩個(gè)方面的問(wèn)題,。接口多態(tài)在現(xiàn)代軟件開(kāi)發(fā)中有著廣泛的應(yīng)用,。 類繼承使得子類自動(dòng)擁有父類大多數(shù)的成員,,C#允許通過(guò)普通的類繼承來(lái)為組件提供多態(tài)能力,。繼承常用于在一個(gè)現(xiàn)有父類基礎(chǔ)上的功能擴(kuò)展,,往往是將幾個(gè)類中相同的成員提取出來(lái)放在父類中實(shí)現(xiàn),然后在各自的子類中加以繼承,。“子類 is a 父類,,蘋(píng)果 is a水果”是繼承多態(tài)的標(biāo)準(zhǔn)測(cè)試用語(yǔ),。繼承對(duì)于小規(guī)模的軟件開(kāi)發(fā)多有裨益,,但在現(xiàn)代集群組件開(kāi)發(fā)模式下,,由于常常引入晦澀的邏輯和不必要的編碼負(fù)擔(dān),,它通常不被推薦使用,。 抽象多態(tài)是指通過(guò)abstract(抽象)類同時(shí)實(shí)現(xiàn)繼承和接口的多態(tài)功能。抽象類中既可以包括實(shí)現(xiàn)了的成員,,也可以是僅僅提供成員接口而沒(méi)有具體實(shí)現(xiàn),。抽象類不能被實(shí)例化,,必須在其繼承類中實(shí)現(xiàn)相應(yīng)的接口,,否則子類也應(yīng)被標(biāo)志為abstract,。抽象類在為其子類提供一個(gè)規(guī)定的功能集的同時(shí),,也為其子類提供了一個(gè)具備擴(kuò)展能力的彈性接口,。抽象類在組件的初始設(shè)計(jì)時(shí)非常有用,,但由于類不能進(jìn)行多繼承,,它的多態(tài)能力較之接口多態(tài)要有所損失,。 |
|
來(lái)自: 遙遠(yuǎn)的橋zz > 《.net學(xué)習(xí)》