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