1. 程式人生 > >C#編程(二十五)----------接口

C#編程(二十五)----------接口

目的 count() 聲明變量 form [] 類的繼承 計算機 構造 執行

接口

如果一個類派生自一個接口,聲明這個類就會實現某些函數.並不是所有的面向對象的語言都支持接口.

例如,有一個接口:IDispoable,包含一個方法Dispose(),該方法又類實現,用於清理代碼:

public interface IDisposable

{

void Dispose();

}

上述代碼說明,聲明接口在語法上與聲明抽象類完全相同,但不允許提供接口中任何成員的實現方式.一般情況下,接口只能包含方法,屬性,索引器和事件的聲明.

不能實例化接口,他只能包含mount成員的二千名.接口既不能有構造函數,也不能有字段.接口定義也不允許包含運算符重載.

在接口定義中還不允許聲明關於成員的修飾符.接口成員總是共有的,不能聲明為虛擬或靜態.如果需要,就有實現的類來聲明,因此最好實現執行的類來聲明訪問修飾符.

例如上面的IDisposable接口中的Disposable方法.

class SomeClass : IDisposable

{

public void Disposable()

{

}

}

在這個例子中,如果SomeClass派生自IDisposable,但沒有實現Disposable(),就會得到一個編譯錯誤,因為該類破壞了實現的IDisposable的一致協定.當然,編譯器允許類有一個不派生自IDisposable類的Disposable()方法.問題是其他代碼無法識別出SomeClass類支持的IDisposable特性.

定義和實現接口

下面開發一個遵循接口繼承規範的小例子說明如何定義和實現接口.編寫代碼,最終允許在銀行賬戶之間進行計算機轉賬業務.許多公司可以實現銀行賬戶,但他們都是彼此贊同表示銀行賬戶的所有類都實現接口IBankAccount.該接口包含一個用於存款的方法和一個返回余額的屬性.

我們的目的是允許銀行賬戶彼此通信,以便在賬戶之間進行轉賬業務.

首先定義接口:

public interface IBankAccount

{

void PayIn(decimal amount);

bool Withdraw(decimal amount);

decimal Balance

{

get;

}

}

註意接口的名稱為IBankAccount.接口的名稱通常是以字母I開頭,以便知道這是一個借口.

現在編寫表示銀行賬戶的類.這些類不必彼此相關,他們可以是完全不同的類.但他們都表示銀行賬戶,因為他們都實現了IBankAccount接口.

第一個類:

public class SavaAccount:IBankAccount

{

private decimal balance;

public void PayIn(decimal amount)

{

balance += amount;

}

public bool Withdraw(decimal amount)

{

if (balance>=amount)

{

balance -= amount;

return true;

}

Console.WriteLine("Withdrawal attempt failed. "); ;

return false;

}

public decimal Balance

{

get

{

return balance;

}

}

public override string ToString()

{

return string.Format("Venus Bank Saver : Balance ={0,6}:C",balance);

}

}

這個類包含了一個私有字段balance,當存款或取款時就調整這個字段.如果因為賬戶中的金額不足而取款失敗,就會顯示一條錯誤信息.

接下來看這個類的聲明:

public class SavaAccount : IBankAccount

SavaAccount 派生自一個接口IBankAccount,我們沒有明確指出任何其他積累.另外,從接口中派生完全獨立與類中派生.

SavaAccount 派生自IBankAccount,表示它獲得了IBankAccount的所有成員,但接口實際上並沒有實現其方法,所以SavaAccount 必須提供這些方法的所有實現代碼.如果缺少實現代碼,編譯器就會產生錯誤.

接口僅表示其成員的存在性,類負責確定這些成員是虛擬的還是抽象的(但只有在類本身是抽象的,這些函數才能是抽象)

另一個類:

public class GoldAccount : IBankAccount

{內容和SavaAccount類一樣}

然後再Main()方法中:

static void Main(string[] args)

{

IBankAccount venusAccount = new SvaAccount();

IBankAccount jupiterAccount = new GoldAccount();

venusAccount.PayIn(200);

venusAccount.Withdraw(100);

Console.WriteLine(venusAccount.ToString());

jupiterAccount.PayIn(500);

jupiterAccount.Withdraw(600);

jupiterAccount.Withdraw(100);

Console.WriteLine(jupiterAccount.ToString()); ;

Console.ReadKey();

}

輸出為:

Venus Bank Saver : Balance = 100$:

Withdrawal attempt failed.

jupit Bank Saver : Balance = 400$:

以上代碼中,要點是把兩個引用聲明變量為IBankAccount引用的方式.這表示他們可以指向實現這個借口的任何類的任何實例.但我們只能通過這些引用調用接口的一部分方法----如果要調用由類實現的但不在接口中的方法,就需要把引用強制轉換為合適的類型.我們調用了ToString(),但沒有進行任何顯示的強制轉換,這是因為ToString()是一個object方法,因此C#編譯器知道任何類都支持這個方法(換句話說,從人和接口到object的數據類型強制轉換為隱式的)

接口引用完全可以看做是類引用----但接口引用的強大之處在於,可以引用任何實現該接口的類.例如,我們可以構造接口數組,其中數組的每個元素都是不同的類:

IBankAccount[] accounts = new IBankAccount[2];

accounts[0] = new SvaAccount();

accounts[1] = new GoldAccount();

但是如果出現一個沒有繼承該接口的類就出現錯誤:

例如:

accounts[0] = new SomeClassAccount();這是錯誤的.

派生的接口

接口可以彼此派生,其方式與類的繼承方式相同.下面通過定義一個新的接口ITransferBankAccount來說明這個概念,該接口的功能與IBankAccount相同,只是定義了一個方法,把資金轉到另一個賬戶上.

定義該接口:

interface ITransferBankAccount:IBankAccount

{

bool TransferTo(IBankAccount destination, decimal amount);

}

因為ITransferBankAccount派生自IBankAccount,所以它擁有IBankAccount的所有成員和它自己的成員.這表示實現(派生自)ITransferBankAccount的任何類都必須實現IBankAccount的所有方法和在ITransferBankAccount中定義的新方法TransferTo().沒有實現這些所有的方法就會報錯.

註意TransferTo()方法對於目標賬戶使用了IBankAccount接口引用.這說明了接口的用途:在實現並調用這個方法是,不必知道轉賬的對象類型,只需要知道該對象實現了IBankAccount即可.

下面說明ITransferBankAccount:假定Jupiter還提供了一個當前賬戶.CurrentAccount類的大多數實現代碼與SvaAccountGoldAccount的實現代碼相同.

public class CurrentAccount:ITransferBankAccount

{

private decimal balance;

public void PayIn(decimal amount)

{

balance += amount;

}

public bool Withdraw(decimal amount)

{

if (balance >= amount)

{

balance -= amount;

return true;

}

Console.WriteLine("Withdrawal attempt failed. "); ;

return false;

}

public decimal Balance

{

get

{

return balance;

}

}

public override string ToString()

{

return string.Format("jupit Bank Current Account : Balance ={0,6}$:", balance);

}

public bool TransferTo(IBankAccount destination, decimal amount)

{

bool result;

result = Withdraw(amount);

if (result)

{

destination.PayIn(amount);

}

return result;

}

}

Main()函數的內容:

IBankAccount venusAccount = new SvaAccount();

ITransferBankAccount jupiterAccount = new CurrentAccount();

venusAccount.PayIn(200);

jupiterAccount.PayIn(500);

jupiterAccount.TransferTo(venusAccount, 100);

Console.WriteLine(venusAccount.ToString());

Console.WriteLine(jupiterAccount.ToString());

Console.ReadKey();

輸出結果為:

Venus Bank Saver : Balance = 300$:

jupit Bank Current Account : Balance = 400$:

表示轉賬成功

C#編程(二十五)----------接口