總結(jié)和學(xué)習(xí)C#接口
什么是C#接口?其實(shí),接口簡(jiǎn)單理解就是一種約定,使得實(shí)現(xiàn)接口的類或結(jié)構(gòu)在形式上保持一致。個(gè)人覺(jué)得,使用接口可以使程序更加清晰和條理化,這就是接口的好處,但并不是所有的編程語(yǔ)言都支持接口,C#是支持接口的。注意,雖然在概念上,C#接口類似于COM接口,但他們的底層結(jié)構(gòu)是不同的。那么,我們來(lái)看一下如何聲明和使用接口。
學(xué)習(xí)C#接口:聲明接口
聲明接口在語(yǔ)法上和聲明抽象類完全相同,例如這里有一個(gè)銀行賬戶的接口:
- public interface IBankAccount
- {
- void PayIn(decimal amount);
- bool Withdraw(decimal amount);
- decimal Balance
- {
- get;
- }
- }
注意:接口中只能包含方法、屬性、索引器和事件的聲明。不允許聲明成員上的修飾符,即使是pubilc都不行,因?yàn)榻涌诔蓡T總是公有的,也不能聲明為虛擬和靜態(tài)的。如果需要修飾符,***讓實(shí)現(xiàn)類來(lái)聲明。
學(xué)習(xí)C#接口:使用C#接口的例子
這是書(shū)上的一個(gè)簡(jiǎn)單的例子,但足以說(shuō)明接口的使用方法。
一個(gè)銀行賬戶的接口,兩個(gè)不同銀行賬戶的實(shí)現(xiàn)類,都繼承于這個(gè)接口。接口聲明如上。下面是兩個(gè)賬戶類:
- class SaverAccount : IBankAccount
- {
- private decimal balance;
- public decimal Balance
- {
- get
- {
- return balance;
- }
- }
- public void PayIn(decimal amount)
- {
- balance += amount;
- }
- public bool Withdraw(decimal amount)
- {
- if (balance >= amount)
- {
- balance -= amount;
- return true;
- }
- Console.WriteLine("Withdraw failed.");
- return false;
- }
- public override string ToString()
- {
- return String.Format("Venus Bank Saver:Balance={0,6:C}", balance);
- }
- }
- class GoldAccount : IBankAccount
- {
- private decimal balance;
- public decimal Balance
- {
- get
- {
- return balance;
- }
- }
- public void PayIn(decimal amount)
- {
- balance += amount;
- }
- public bool Withdraw(decimal amount)
- {
- if (balance >= amount)
- {
- balance -= amount;
- return true;
- }
- Console.WriteLine("Withdraw failed.");
- return false;
- }
- public override string ToString()
- {
- return String.Format("Jupiter Bank Saver:Balance={0,6:C}", balance);
- }
- }
可見(jiàn),這兩個(gè)實(shí)現(xiàn)類多繼承了IBankAccount接口,因此它們必須要實(shí)現(xiàn)接口中的所有聲明的方法。要不然,編譯就會(huì)出錯(cuò)。讓我們來(lái)測(cè)試一下,下面是測(cè)試代碼:
- static void Main(string[] args)
- {
- IBankAccount venusAccount = new SaverAccount();
- IBankAccount jupiterAccount = new CurrentAccount();
- venusAccount.PayIn(200);
- jupiterAccount.PayIn(500);
- Console.WriteLine(venusAccount.ToString());
- jupiterAccount.PayIn(400);
- jupiterAccount.Withdraw(500);
- jupiterAccount.Withdraw(100);
- Console.WriteLine(jupiterAccount.ToString());
- }
請(qǐng)注意開(kāi)頭兩句,我們把它們聲明為IBankAccount引用的方式,而沒(méi)有聲明為類的引用,為什么呢?因?yàn)?,這樣我們就可以讓它指向執(zhí)行這個(gè)接口的任何類的實(shí)例了,比較靈活。但這也有個(gè)缺點(diǎn),如果我們要執(zhí)行不屬于接口的方法,比如這里重載的ToString()方法,就要先把接口的引用強(qiáng)制轉(zhuǎn)換成合適的類型了。
接口的繼承
接口也可以彼此繼承,就象類的繼承一樣。比如我們又聲明一個(gè)接口ITransferBankAccount,它繼承于IBankAccount接口。
- interface ITransferBankAccount : IBankAccount
- {
- bool TransferTo(IBankAccount destination, decimal amount);
- }
在這個(gè)接口中,又新增加了一個(gè)方法TransferTo(),所以如果我們要寫(xiě)一個(gè)類從ITransferBankAccount繼承的話,就必須要實(shí)現(xiàn)IBankAccount和ITransferBankAccount兩個(gè)接口所有的方法聲明。即:
- class CurrentAccount : ITransferBankAccount
- {
- private decimal balance;
- public decimal Balance
- {
- get
- {
- return balance;
- }
- }
- public void PayIn(decimal amount)
- {
- balance += amount;
- }
- public bool Withdraw(decimal amount)
- {
- if (balance >= amount)
- {
- balance -= amount;
- return true;
- }
- Console.WriteLine("Withdraw failed.");
- return false;
- }
- public override string ToString()
- {
- return String.Format("Jupiter Bank Saver:Balance={0,6:C}", balance);
- }
- public bool TransferTo(IBankAccount destination, decimal amount)
- {
- if (Withdraw(amount))
- {
- destination.PayIn(amount);
- return true;
- }
- else
- {
- return false;
- }
- }
- }
總結(jié)起來(lái)說(shuō),使用學(xué)習(xí)C#接口應(yīng)注意幾個(gè)問(wèn)題:
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è)類派生。
【編輯推薦】