本章节主要讲解关于继承的一些内容,不会具体讲如何实现继承,只是讲解出现的一些问题。
3.1 继承的类型
1.实现继承:
表示一个类型派生于一个基类型,拥有该类型的所有成员字段和函数。
2.接口继承:
表示一个类型只继承了函数的签名,没有继承任何实现代码。
3.2 实现继承
1.virtual虚方法
把一个基类函数声明为virtual,该函数就可以派生类中重写了:
virtual示例
class MyBaseClass
{
public virtual string Method()//虚方法
{
return "this is virtual method";
}
}
class ChildMyClass:MyBaseClass
{
public override string Method()//override
{
return "this is child override method";
}
}
{
public virtual string Method()//虚方法
{
return "this is virtual method";
}
}
class ChildMyClass:MyBaseClass
{
public override string Method()//override
{
return "this is child override method";
}
}
说明:vitru al只对类中的实例话函数成有有意义,也就是静态函数是不能声明为virtual
2. 隐藏方法
如果有相同的方法在基类和派生类中都进行了声明,但该方法没有声明为virtual和override,派生类方法将会自动隐藏基类方法。
隐藏基类demo
public class HideBaseClass
{
public string HideMethod()
{
return "Parent HideMethod";
}
}
public class ChildHideClass:HideBaseClass
{
public string HideMethod()
{
return "Child HideMethod";
}
}
{
public string HideMethod()
{
return "Parent HideMethod";
}
}
public class ChildHideClass:HideBaseClass
{
public string HideMethod()
{
return "Child HideMethod";
}
}
上面的示例编译器将提示子类方法与基类方法有冲突。在C#中,应使用new 关键字声明隐藏这一个方法,如下代码:
实现隐藏一个方法
public class ChildHideClass:HideBaseClass
{
public new string HideMethod()
{
return "Child HideMethod";
}
}
{
public new string HideMethod()
{
return "Child HideMethod";
}
}
当然遇到这种情况我们最好避免重名,最好修改方法名称。
3.调用函数基类版本
调用基类示例
class CustomerAccount
{
public virtual decimal CalculatePrice()
{
return 1.0M;
}
}
class GoldAccount:CustomerAccount
{
public override decimal CalculatePrice()
{
return base.CalculatePrice()*0.9M;
}
}
{
public virtual decimal CalculatePrice()
{
return 1.0M;
}
}
class GoldAccount:CustomerAccount
{
public override decimal CalculatePrice()
{
return base.CalculatePrice()*0.9M;
}
}
4.抽象类和抽象方法
C#允许把类和方法声明为abstract,抽象类不能实例化,而抽象函数没有执行代码,必须在非抽象的派生类中重写。如果类中有抽象方法,那么该类也是抽象的,也必须设定为抽象的:
抽象方法示例
abstract class UserAccount
{
public abstract decimal CalculatePrice();
}
class SalaryAccount : UserAccount
{
public override decimal CalculatePrice()
{
return 0.9M;
}
}
{
public abstract decimal CalculatePrice();
}
class SalaryAccount : UserAccount
{
public override decimal CalculatePrice()
{
return 0.9M;
}
}
5.密封类和密封方法
C#允许对方法和类使用sealed,对于类来讲他不能够被继承,对于方法来言,这个方法不能重写了。
一般通常使用这个声明,都是在商业软件中,防止类重写某些功能出错误。
3.3实现接口
1.定义和实现接口
定义接口和实现接口
#region 定义接口和实现接口
public interface IBankAccount
{
void PayIn(decimal amount);
bool Withdraw(decimal amount);
decimal Balance
{
get;
}
}
public class SaveAccount:IBankAccount
{
private decimal balance;
public void PayIn(decimal amount)
{
balance += amount;
}
public bool Withdraw(decimal accoumt)
{
if (balance>=accoumt)
{
balance -= accoumt;
return true;
}
Console.WriteLine("withdraw attempt failed");
return false;
}
public decimal Balance
{
get
{
return balance;
}
}
public override string ToString()
{
return string.Format("this is a balance={0,6:C}", balance);
}
}
#endregion
public interface IBankAccount
{
void PayIn(decimal amount);
bool Withdraw(decimal amount);
decimal Balance
{
get;
}
}
public class SaveAccount:IBankAccount
{
private decimal balance;
public void PayIn(decimal amount)
{
balance += amount;
}
public bool Withdraw(decimal accoumt)
{
if (balance>=accoumt)
{
balance -= accoumt;
return true;
}
Console.WriteLine("withdraw attempt failed");
return false;
}
public decimal Balance
{
get
{
return balance;
}
}
public override string ToString()
{
return string.Format("this is a balance={0,6:C}", balance);
}
}
#endregion
2.派生的接口
接口可以彼此继承,其方式和类得继承是相同。下面定义一个方法,把资金直接转到另一个账号上去。
接口的继承示例
#region 定义接口和实现接口
public interface IBankAccount
{
void PayIn(decimal amount);
bool Withdraw(decimal amount);
decimal Balance
{
get;
}
}
public interface ITransferBankAccount : IBankAccount
{
bool TransferTo(IBankAccount destination, decimal amount);
}
public class SaveAccount:IBankAccount
{
private decimal balance;
public void PayIn(decimal amount)
{
balance += amount;
}
public bool Withdraw(decimal accoumt)
{
if (balance>=accoumt)
{
balance -= accoumt;
return true;
}
Console.WriteLine("withdraw attempt failed");
return false;
}
public decimal Balance
{
get
{
return balance;
}
}
public override string ToString()
{
return string.Format("this is a balance={0,6:C}", balance);
}
}
//当前账号
public class CurrentAccount:ITransferBankAccount
{
private decimal balance;
public void PayIn(decimal amount)
{
balance += amount;
}
public bool Withdraw(decimal accoumt)
{
if (balance >= accoumt)
{
balance -= accoumt;
return true;
}
Console.WriteLine("withdraw 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("this is a CurrentAccount={0,6:C}", balance);
}
}
#endregion
public interface IBankAccount
{
void PayIn(decimal amount);
bool Withdraw(decimal amount);
decimal Balance
{
get;
}
}
public interface ITransferBankAccount : IBankAccount
{
bool TransferTo(IBankAccount destination, decimal amount);
}
public class SaveAccount:IBankAccount
{
private decimal balance;
public void PayIn(decimal amount)
{
balance += amount;
}
public bool Withdraw(decimal accoumt)
{
if (balance>=accoumt)
{
balance -= accoumt;
return true;
}
Console.WriteLine("withdraw attempt failed");
return false;
}
public decimal Balance
{
get
{
return balance;
}
}
public override string ToString()
{
return string.Format("this is a balance={0,6:C}", balance);
}
}
//当前账号
public class CurrentAccount:ITransferBankAccount
{
private decimal balance;
public void PayIn(decimal amount)
{
balance += amount;
}
public bool Withdraw(decimal accoumt)
{
if (balance >= accoumt)
{
balance -= accoumt;
return true;
}
Console.WriteLine("withdraw 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("this is a CurrentAccount={0,6:C}", balance);
}
}
#endregion
小结:本章节讲了继承和接口的一些细节问题,比如virtual,接口的继承等。