• 接口


    接口使用interface关键字进行定义,例如

    interface IComparable

    {

      int CompareTo(object obj);

    }

    接口描述可属于任何类或结构的一组相关行为。接口可由方法,属性,事件,索引器或这4种成员类型的任何组合构成。接口不能包含字段,接口成员一定是公共的。类和结构可以像类继承基类或结构一样从接口继承,但有两个例外:

    (1)类或结构课继承多个接口

    (2)当类或结构继承接口时,它继承成员定义,但不继承实现

    接口在面向对象编程中起着非常重要的作用,是我们后面要用到的工厂,多层架构等的重要组成部分。下面通过一个小的例子来看接口所带来的方便

    预先定义一个接口为小狗

    public interface IDog

    {

      void Bark();

    }

    然后定义一个类MyDog来实现接口IDog,要注意的是,在类中必须要实现接口的方法,即使方法内是空的也必须要写上。

    public class MyDog:IDog

    {

      public void Bark()

      {

        Console.WriteLine("wang,wang");

      }

    }

    如果你的小狗某天会飞了,就成了

    public class MyDog:IDog

    {

      public void Bark()

      {

        Console.WriteLine("wang,wang");

      }

      public void Fly()

      {

        Console.WriteLine("Flying now");

      }

    }

    一般的情况下我们不去扩张原来的接口IDog,可以看出,把Fly方法放入IDog是不合理的(不是所有的小狗都会飞)。这时应该定义新接口给Fly方法

    public interface IFlyable

    {

      void Fly();

    }

    然后MyDog的实现应该如下:

    public class MyDog:IDog,IFlyable

    {

      public void Bark()

      {

        Console.WriteLine("wang,wang");

      }

      public void Fly()

      {

        Console.WriteLine("Flying now");

      }

    }

    这样的好处是什么呢?比如在某个地方用到MyDog,如MyHoouse.直接放入MyDog会怎么样?

    public class MyHouse

    {

      MyDog mydog=null;

      public MyHouse(MyDog dog)

      {

        mydog=dog;

      }

      //有人进来,狗叫

      public void ComeIn()

      {

        mydog.Bark();

      }

      //拍电影,狗飞

      public void ShootMovie()

      {

        mydog.Fly();

      }

    }

    但有一天需求改变了(软件里面需求改变是正确的),要求换你的狗而不是我的狗

    public class YourDog:IDog,IFlyable

    {

      public void Bark()

      {

        Console.WriteLine("wang,wang");

      }

      public void fly()

      {

        Console.WriteLine("Flying now");

      }

    }

    MyHouse怎么办?重新实现一遍?原来的MyHouse其实还有一个坏处是“与MyDog是紧密耦合的”。当代软件不够灵活的地方就在于紧耦合,而接口正是解决这种情况的灵丹妙药。所以一开始就不应该让MyHouse和MyDog紧密耦合,而应该对接口进行编程,代码如下

    public void MyHouse

    {

      IDog _dog=null;

      IFlyable _flyer=null;

      public MyHouse(IDog dog,IFlyable flyer)

      {

        _dog=dog;

        _flyer=flyer;

      }

      //有人进来,狗叫

      public void ComeIn()

      {

        _dog.Bark();

      }

      //拍电影

      public void ShootMovie()

      {

        _flyer.Fly();

      }

    }

    这样无论是传MyDog或YourDog都可以,例如:

    MyHouse house=new MyHouse (new MyDog(),new MyDog());

    MyHouse house=new MyHouse(new YourDog(),new YourDog());

    甚至还可以让MyDog在ComeIn里面叫唤,让YourDog在ShootMovie里面拍电影

    例如:

    MyHouse house=new MyHouse(new MyDog(),new YourDog());

  • 相关阅读:
    为什么你SQL Server的数据库文件的Date modified没有变化呢?
    SQL Server中SELECT会真的阻塞SELECT吗?
    ORACLE从共享池删除指定SQL的执行计划
    flink DataStream API使用及原理
    漫谈九品中正制和现阶段阶层分层
    flink dataset api使用及原理
    从flink-example分析flink组件(3)WordCount 流式实战及源码分析
    TODO supply a title
    avalon2学习教程01
    avalon1与avalon2的异同点
  • 原文地址:https://www.cnblogs.com/yk1992/p/3587301.html
Copyright © 2020-2023  润新知