c#学习笔记 021 (修饰符、接口)

2009年1月29日星期四

c#学习笔记 021 (修饰符、接口)

一、修饰符。

就是应用于类型或成员的关键字。

1、可见性修饰符。

public 应用于所有的类型或成员 任何代码均可以访问该方法

protected 类和内嵌类的所有成员 只有派生的类能访问该方法

internal 类和内嵌类的所有成员 只能在包含它的程序集中访问该方法

private 所有的类或成员 只能在它所属的类中访问该方法

protected internal 类和内嵌类的所有成员 只能在包含它的程序集和派生类的代码中访问该方法

类定义可以是内部的或公共的,不能定义为protected、private和protected internal,如果一个类是另一个类的成员,则可以使用。

如果有嵌套的成员,内部的类总是可以访问外部类的所有成员,包括私有成员。

2、其他修饰符。

new 函数成员 成员用相同的签名隐藏继承成员

static 所有的成员 成员不在类的具体实例上执行

virtual 仅类和函数成员 成员可以由派生类重写

abstract 仅函数成员 虚拟成员定义了成员的签名,但没有提供实现代码

override 仅函数成员 成员重写了继承的虚拟或抽象成员

sealed 类、方法和属性密封类不能继承。对于属性和方法,成员重写了继承的虚拟成员,但继承该类的任何类都不能重写该成员,该修饰符必须与override一起使用

extern 仅静态方法 成员在外部用另一种语言实现

二、接口

如果一个类派生于一个接口,它就会执行某些函数。

接口中只能包含方法、属性、索引器和事件的声明。

例如:

public interfacd IDisposable
{
void Dispose();
}

不能实例化接口,接口不能有构造函数或字段,不能包含运算符重载。

不允许声明成员上的修饰符。接口总是公共的。不能是虚拟的或静态的。

如果希望声明为公共的应由执行的类来声明,例如:

class SomeClass : IDispossable
{
//this class MUST contain an implementation of the
//IDisposable.Dispose() method,otherwise
//you get a compilation error
public void Dispose()
{
//implementation of Dispose() method
}
//rest of class
}

1、定义和实现接口。

下面开发一个遵循接口继承规范的小例子。

假定编写代码,最终允许在银行帐户之间进行计算机转账业务,许多公司可以实现银行帐户,但它们都使用共同的实现接口IBankAccount。包含一个用于存取款的方法和一个返回余额的属性。

定义一个IBank接口:

namespace Wrox.ProCSharp
{
public interface IBankAccount
{
void PayIn(decimal amount);
bool Withdraw(decimal amount);
decimal Balance
{
get;
}
}
}

下面是第一个类,实现该接口的某个银行的帐户类。

namespace Wrox.ProCSharp.VenusBank
{
public class SaverAccount : 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);
}
}
}

SaverAccount派生于IBankAccount,表示它获得了IBankAccount的所有成员,但接口并不实际实现其方法,所以SaverAccount必须提供这些方法的所有实现代码。如果没有实现代码,编译器会报错。

建立另一个银行的帐户类

namespace Wrox.ProCSharp.JupiterBank
{
public class GoldAccount: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("Jupiter Bank Saver: Balance = {0,6:C}",balance);
}
}
}

为了测试我们还要一个Main()方法

using System;
using Wrox.ProCSharp;
using Wrox.ProCSharp.VenusBank;
using Wrox.ProCSharp.JupiterBank;

namespace Wrox.ProCSharp
{
class MainEntryPoint
{
static void Main()
{
IBankAccount venusAccount=new SaverAccount();
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());
}
}
}

执行结果如下:

D:\c#001>mainentrypoint
Venus Bank Saver: Balance = ¥100.00
Withdrawal attempt failed.
Jupiter Bank Saver: Balance = ¥400.00

我们使用了接口引用,接口引用可以象类引用那样使用,但是只能访问接口中有的成员,如果要访问类中的成员(非继承接口得来的成员)就要使用适当的强制转换。

接口引用的强大之处在于,它可以引用任何实现该接口的类,例如可以构造接口数组,其中的每个元素都是不同的类:

IBankAccount[] accounts=new IBankAccount[2];
accounts[0]=new SaverAccount();
accounts[1]=new GoldAccount();

2、派生的接口

定义一个转帐的新接口

namespace Wrox.ProCSharp
{
public interface ITransferBankAccount:IBankAccount
{
bool TransferTo(IBankAccount destination,decimal amount);
}
}

执行ITramsferBankAccount的任何类都必须执行IBankAccount的所有方法和在ITransferBankAccount中定义的新方法TransferTo()。

注意:TransferTo()方法为目标帐户使用了IBankAccount接口引用。这说明了接口的用途:在执行并调用这个方法时,不必知道转账的对象类型,只需要知道该对象执行IBankAccount即可。

下面演示一下接口继承的应用:在JupiterBank中增加一个CurrentAccount帐户。

using System;
using Wrox.ProCSharp;
using Wrox.ProCSharp.VenusBank;
using Wrox.ProCSharp.JupiterBank;

namespace Wrox.ProCSharp
{
public interface ITransferBankAccount:IBankAccount
{
bool TransferTo(IBankAccount destination,decimal amount);
}
}

namespace Wrox.ProCSharp
{
public interface IBankAccount
{
void PayIn(decimal amount);
bool Withdraw(decimal amount);
decimal Balance
{
get;
}
}
}

namespace Wrox.ProCSharp.VenusBank
{
public class SaverAccount : 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);
}
}
}

namespace Wrox.ProCSharp.JupiterBank
{
public class GoldAccount: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("Jupiter Bank Saver: Balance = {0,6:C}",balance);
}
}
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 bool TransferTo(IBankAccount destination,decimal amount)
{
bool result;
if ((result=Withdraw(amount))==true)
{
destination.PayIn(amount);
}
return result;
}
public override String ToString()
{
return String.Format("Jupiter Bank Saver: Balance = {0,6:C}",balance);
}
}
}

namespace Wrox.ProCSharp
{
class MainEntryPoint
{
static void Main()
{
IBankAccount venusAccount=new SaverAccount();
ITransferBankAccount jupiterAccount=new CurrentAccount();
venusAccount.PayIn(200);
jupiterAccount.PayIn(500);
jupiterAccount.TransferTo(venusAccount,100);
Console.WriteLine(venusAccount.ToString());
Console.WriteLine(jupiterAccount.ToString());
}
}
}

执行结果如下:

D:\c#001>mainentrypoint1
Venus Bank Saver: Balance = ¥300.00
Jupiter Bank Saver: Balance = ¥400.00

    0 评论:

    发表评论