zoukankan      html  css  js  c++  java
  • C#编程(二十五)----------接口

    接口

    如果一个类派生自一个接口,声明这个类就会实现某些函数.并不是所有的面向对象的语言都支持接口.

    例如,有一个接口: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$:

    表示转账成功

  • 相关阅读:
    hibernate的缓存机制
    [poj 3159]Candies[差分约束详解][朴素的考虑法]
    POJ 2773 Happy 2006
    给定一个循环链表,实现一个算法返回这个环的开始结点
    使用jQuery创建模态窗口登陆效果
    实战数据结构(3)_两个单链表间的合并操作
    sql的强大功能(看一条sql解决的复杂业务)
    uva 10905 Children's Game (排序)
    JFinal学习 & Gradle配置续 & Tomcat配置
    Gradle项目学习 & HttpAsyncClient学习 & CountDownLatch学习
  • 原文地址:https://www.cnblogs.com/FinleyJiang/p/7602503.html
Copyright © 2011-2022 走看看