淺析C#接口之獲取IP地址
我們今天要討論C#接口之獲取IP地址,通過(guò)這一實(shí)例,我們能更深刻的了解C#接口。希望本文能對(duì)大家了解C#接口有所幫助。
通過(guò)對(duì)IP地址獲取的了解,由于對(duì)業(yè)務(wù)不甚了解,我采用接口編程來(lái)實(shí)現(xiàn)getIP():
接口好比一種模版,這種模版定義了對(duì)象必須實(shí)現(xiàn)的方法,其目的就是讓這些方法可以作為接口實(shí)例被引用。接口不能被實(shí)例化。類可以實(shí)現(xiàn)多個(gè)接口并且通過(guò)這些實(shí)現(xiàn)的接口被索引。接口變量只能索引實(shí)現(xiàn)該接口的類的實(shí)例。
說(shuō)明:
1、C#中的接口是獨(dú)立于類來(lái)定義的。這與C++模型是對(duì)立的,在 C++中接口實(shí)際上就是抽象基類。
2、接口和類都可以繼承多個(gè)接口。
3、而類可以繼承一個(gè)基類,接口根本不能繼承類。這種模型避免了 C++的多繼承問(wèn)題,C++中不同基類中的實(shí)現(xiàn)可能出現(xiàn)沖突。因此也不再需要諸如虛擬繼承和顯式作用域這類復(fù)雜機(jī)制。C#的簡(jiǎn)化接口模型有助于加快應(yīng)用程序的開(kāi)發(fā)。
4、一個(gè)接口定義一個(gè)只有抽象成員的引用類型。C#中一個(gè)接口實(shí)際所做的,僅僅只存在著方法標(biāo)志,但根本就沒(méi)有執(zhí)行代碼。這就暗示了不能實(shí)例化一個(gè)接口,只能實(shí)例化一個(gè)派生自該接口的對(duì)象。
5、接口可以定義方法、屬性和索引。所以,對(duì)比一個(gè)類,接口的特殊性是:當(dāng)定義一個(gè)類時(shí),可以派生自多重接口,而你只能可以從僅有的一個(gè)類派生。
(一)定義接口:
從技術(shù)上講,接口是一組包含了函數(shù)型方法的數(shù)據(jù)結(jié)構(gòu)。通過(guò)這組數(shù)據(jù)結(jié)構(gòu),客戶代碼可以調(diào)用組件對(duì)象的功能。
定義接口的一般形式為:
[attributes] [modifiers] interface identifier [:base-list] {interface-body}[;]
說(shuō)明:
1、attributes(可選):附加的定義性信息。
2、modifiers(可選): 允許使用的修飾符有 new 和四個(gè)訪問(wèn)修飾符。分別是:new、public、protected、internal、 private。在一個(gè)接口定義中同一修飾符不允許出現(xiàn)多次,new 修飾符只能出現(xiàn)在嵌套接口中,表示覆蓋了繼承而來(lái)的同名成員。The public, protected, internal, and private 修飾符定義了對(duì)接口的訪問(wèn)權(quán)限。
3、指示器和事件。
4、identifier:接口名稱。
5、base-list(可選):包含一個(gè)或多個(gè)顯式基接口的列表,接口間由逗號(hào)分隔。
6、interface-body:對(duì)接口成員的定義。
(二)訪問(wèn)接口:
對(duì)接口方法的調(diào)用和采用索引指示器訪問(wèn)的規(guī)則與類中的情況也是相同的。如果底層成員的命名與繼承而來(lái)的高層成員一致,那么底層成員將覆蓋同名的高層成員。但由于接口支持多繼承,在多繼承中,如果兩個(gè)父接口含有同名的成員,這就產(chǎn)生了二義性(這也正是C#中取消了類的多繼承機(jī)制的原因之一),這時(shí)需要進(jìn)行顯式的定義。
在C#中,接口內(nèi)的所有方法默認(rèn)都是公用方法。
接口可由類實(shí)現(xiàn)。實(shí)現(xiàn)的接口的標(biāo)識(shí)符出現(xiàn)在類的基列表中。
類的基列表同時(shí)包含基類和接口時(shí),列表中首先出現(xiàn)的是基類。
(三)實(shí)現(xiàn)接口:
1、顯式實(shí)現(xiàn)接口成員
為了實(shí)現(xiàn)接口,類可以定義顯式接口成員執(zhí)行體(Explicit interface member implementations)。顯式接口成員執(zhí)行體可以是一個(gè)方法、一個(gè)屬性、一個(gè)事件或者是一個(gè)索引指示器的定義,定義與該成員對(duì)應(yīng)的全權(quán)名應(yīng)保持一致。
2、繼承接口實(shí)現(xiàn)
接口具有不變性,但這并不意味著接口不再發(fā)展。類似于類的繼承性,接口也可以繼承和發(fā)展。
注意:接口繼承和類繼承不同,首先,類繼承不僅是說(shuō)明繼承,而且也是實(shí)現(xiàn)繼承;而接口繼承只是說(shuō)明繼承。也就是說(shuō),派生類可以繼承基類的方法實(shí)現(xiàn),而派生的接口只繼承了父接口的成員方法說(shuō)明,而沒(méi)有繼承父接口的實(shí)現(xiàn),其次,C#中類繼承只允許單繼承,但是接口繼承允許多繼承,一個(gè)子接口可以有多個(gè)父接口。
接口可以從零或多個(gè)接口中繼承。從多個(gè)接口中繼承時(shí),用":"后跟被繼承的接口名字,多個(gè)接口名之間用","分割。被繼承的接口應(yīng)該是可以訪問(wèn)得到的,比如從private 類型或internal 類型的接口中繼承就是不允許的。接口不允許直接或間接地從自身繼承。和類的繼承相似,接口的繼承也形成接口之間的層次結(jié)構(gòu)。
3、重新實(shí)現(xiàn)接口
我們已經(jīng)介紹過(guò),派生類可以對(duì)基類中已經(jīng)定義的成員方法進(jìn)行重載。類似的概念引入到類對(duì)接口的實(shí)現(xiàn)中來(lái),叫做接口的重實(shí)現(xiàn)(re-implementation)。繼承了接口實(shí)現(xiàn)的類可以對(duì)接口進(jìn)行重實(shí)現(xiàn)。這個(gè)接口要求是在類定義的基類列表中出現(xiàn)過(guò)的。對(duì)接口的重實(shí)現(xiàn)也必須嚴(yán)格地遵守首次實(shí)現(xiàn)接口的規(guī)則,派生的接口映射不會(huì)對(duì)為接口的重實(shí)現(xiàn)所建立的接口映射產(chǎn)生任何影響。
4、映射接口
類必須為在基類表中列出的所有接口的成員提供具體的實(shí)現(xiàn)。在類中定位接口成員的實(shí)現(xiàn)稱之為接口映射(interface mapping )。
映射,數(shù)學(xué)上表示一一對(duì)應(yīng)的函數(shù)關(guān)系。接口映射的含義也是一樣,接口通過(guò)類來(lái)實(shí)現(xiàn),那么對(duì)于在接口中定義的每一個(gè)成員,都應(yīng)該對(duì)應(yīng)著類的一個(gè)成員來(lái)為它提供具體的實(shí)現(xiàn)。
類的成員及其所映射的接口成員之間必須滿足下列條件:
1、如果A和B都是成員方法,那么A和B的名稱、類型、形參表(包括參數(shù)個(gè)數(shù)和每一個(gè)參數(shù)的類型)都應(yīng)該是一致的。
2、如果A和B都是屬性,那么A和B的名稱、類型應(yīng)當(dāng)一致,而且A和B的訪問(wèn)器也是類似的。但如果A不是顯式接口成員執(zhí)行體,A允許增加自己的訪問(wèn)器。
3、如果A和B都是時(shí)間那么A和B的名稱、類型應(yīng)當(dāng)一致。
4、如果A和B都是索引指示器,那么A和B的類型、形參表(包括參數(shù)個(gè)數(shù)和每一個(gè)參數(shù)的類型)應(yīng)當(dāng)一致。而且A和B的訪問(wèn)器也是類似的。但如果A不是顯式接口成員執(zhí)行體,A允許增加自己的訪問(wèn)器。
那么,對(duì)于一個(gè)接口成員,怎樣確定由哪一個(gè)類的成員來(lái)實(shí)現(xiàn)呢?即一個(gè)接口成員映射的是哪一個(gè)類的成員?在這里,我們敘述一下接口映射的過(guò)程。假設(shè)類C實(shí)現(xiàn)了一個(gè)接口IInterface,Member是接口IInterface中的一個(gè)成員,在定位由誰(shuí)來(lái)實(shí)現(xiàn)接口成員Member,即Member的映射過(guò)程是這樣的:
1、如果C中存在著一個(gè)顯式接口成員執(zhí)行體,該執(zhí)行體與接口IInterface 及其成員Member相對(duì)應(yīng),則由它來(lái)實(shí)現(xiàn)Member 成員。
2、如果條件(1)不滿足,且C中存在著一個(gè)非靜態(tài)的公有成員,該成員與接口成員Member相對(duì)應(yīng),則由它來(lái)實(shí)現(xiàn)Member 成員。
3、如果上述條件仍不滿足,則在類C定義的基類列表中尋找一個(gè)C 的基類D,用D來(lái)代替C。
4、重復(fù)步驟1-- 3 ,遍歷C的所有直接基類和非直接基類,直到找到一個(gè)滿足條件的類的成員。
5、如果仍然沒(méi)有找到,則報(bào)告錯(cuò)誤。
在進(jìn)行接口映射時(shí),還要注意下面兩點(diǎn):
1、在決定由類中的哪個(gè)成員來(lái)實(shí)現(xiàn)接口成員時(shí),類中顯式說(shuō)明的C#接口成員比其它成員優(yōu)先實(shí)現(xiàn)。
2、使用Private、protected和static修飾符的成員不能參與實(shí)現(xiàn)接口映射。
【編輯推薦】