C#语言学习之旅(3):继承

本章节主要讲解关于继承的一些内容,不会具体讲如何实现继承,只是讲解出现的一些问题。

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";
        }
    }

说明: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";
        }
    }

 上面的示例编译器将提示子类方法与基类方法有冲突。在C#中,应使用new 关键字声明隐藏这一个方法,如下代码:

实现隐藏一个方法
 public class ChildHideClass:HideBaseClass
    {
        
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;
        }
    }

 4.抽象类和抽象方法

 C#允许把类和方法声明为abstract,抽象类不能实例化,而抽象函数没有执行代码,必须在非抽象的派生类中重写。如果类中有抽象方法,那么该类也是抽象的,也必须设定为抽象的:

抽象方法示例
    abstract class UserAccount
    {
         
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

 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

小结:本章节讲了继承和接口的一些细节问题,比如virtual,接口的继承等。

原文地址:https://www.cnblogs.com/mili3/p/2852612.html