zoukankan      html  css  js  c++  java
  • C#学习之接口

      什么是接口?其实,接口简单理解就是一种约定,使得实现接口的类或结构在形式上保持一致。个人觉得,使用接口可以使程序更加清晰和条理化,这就是接口的好处,但并不是所有的编程语言都支持接口,C#是支持接口的。注意,虽然在概念上,C#接口类似于COM接口,但他们的底层结构是不同的。那么,我们来看一下如何声明和使用接口。

      声明接口

      声明接口在语法上和声明抽象类完全相同,例如这里有一个银行账户的接口:
      
    public interface IBankAccount
    {
        
    void PayIn(decimal amount);
        
    bool Withdraw(decimal amount);

        
    decimal Balance
        {
            
    get;
        }
    }

      注意:接口中只能包含方法、属性、索引器和事件的声明。不允许声明成员上的修饰符,即使是pubilc都不行,因为接口成员总是公有的,也不能声明为虚拟和静态的。如果需要修饰符,最好让实现类来声明。

      使用接口的例子

      这是书上的一个简单的例子,但足以说明接口的使用方法。
      一个银行账户的接口,两个不同银行账户的实现类,都继承于这个接口。接口声明如上。下面是两个账户类:

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

      可见,这两个实现类多继承了IBankAccount接口,因此它们必须要实现接口中的所有声明的方法。要不然,编译就会出错。让我们来测试一下,下面是测试代码:

    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());

    }

      请注意开头两句,我们把它们声明为IBankAccount引用的方式,而没有声明为类的引用,为什么呢?因为,这样我们就可以让它指向执行这个接口的任何类的实例了,比较灵活。但这也有个缺点,如果我们要执行不属于接口的方法,比如这里重载的ToString()方法,就要先把接口的引用强制转换成合适的类型了。

      接口的继承

      接口也可以彼此继承,就象类的继承一样。比如我们又声明一个接口ITransferBankAccount,它继承于IBankAccount接口。

    interface ITransferBankAccount : IBankAccount 
    {
        
    bool TransferTo(IBankAccount destination, decimal amount);
    }

      在这个接口中,又新增加了一个方法TransferTo(),所以如果我们要写一个类从ITransferBankAccount继承的话,就必须要实现IBankAccount和ITransferBankAccount两个接口所有的方法声明。即:

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

        }

    }

      总结起来说,使用C#接口应注意几个问题:

      1、C#中的接口是独立于类来定义的。这与 C++模型是对立的,在 C++中接口实际上就是抽象基类。

      2、接口和类都可以继承多个接口。

      3、类可以继承一个基类,接口根本不能继承类。这种模型避免了 C++的多继承问题,C++中不同基类中的实现可能出现冲突。因此也不再需要诸如虚拟继承和显式作用域这类复杂机制。C#的简化接口模型有助于加快应用程序的开发。

      4、一个接口定义一个只有抽象成员的引用类型。C#中一个接口实际所做的,仅仅只存在着方法标志,但根本就没有执行代码。这就暗示了不能实例化一个接口,只能实例化一个派生自该接口的对象。

      5、接口可以定义方法、属性和索引。所以,对比一个类,接口的特殊性是:当定义一个类时,可以派生自多重接口,而你只能可以从仅有的一个类派生。

     
     
  • 相关阅读:
    LeetCode15 3Sum
    LeetCode10 Regular Expression Matching
    LeetCode20 Valid Parentheses
    LeetCode21 Merge Two Sorted Lists
    LeetCode13 Roman to Integer
    LeetCode12 Integer to Roman
    LeetCode11 Container With Most Water
    LeetCode19 Remove Nth Node From End of List
    LeetCode14 Longest Common Prefix
    LeetCode9 Palindrome Number
  • 原文地址:https://www.cnblogs.com/michaelxu/p/692021.html
Copyright © 2011-2022 走看看