接口

接口的定义

  • 接口是一种自定义数据类型。所以写在namespace里。
  • 接口表示一组抽象的功能。

    功能是用函数表示的。
    之所以是抽象的功能是因为接口只是定义了有这些功能,而并没有说明如果实现这些功能,也就是说只有函数的申明,没有函数体。

    namespace LiKang
    {
        // 开关的接口
        interface ISwitch
        {
            // 开
            void Open();
            // 关
            void Close();
        }
    }
    

接口的继承

  • 接口是可以继承的。继承后子接口拥有父接口所有的函数声明。
  • 接口继承的语法和类继承的语法一样。
    namespace LiKang
    {
      // 3态开关的接口
      interface IThreeStateSwitch : ISwitch
      {
          // 半开
          void Half();
      }
    }
    

接口的实现

  • 类可以去实现接口,所谓的实现就是给接口中所有函数申明加上函数体。
  • 实现接口的语法与继承类的语法一样。

    // 灯
    class Light : ISwitch
    {
      // 亮度
      public int Power{ get; set;}
    
      // 这里实现了接口中的Open方法
      public void Open()
      {
          Power = 10;
      }
    
      // 这里实现了接口中的Close方法
      public void Close()
      {
          Power = 0;
      }
    }
    // 门
    class Door : ISwitch
    {
      // 打开的角度
      public int Degree{ get; set;}
    
      // 这里实现了接口中的Open方法
      public void Open()
      {
          Degree = 90;
      }
    
      // 这里实现了接口中的Close方法
      public void Close()
      {
          Degree = 0;
      }
    }
    

接口的编程思想

你可能会想不使用ISwitch接口也可以去定义OpenClose方法呀,为什么一定要实现这个接口呢?
Light类实现了ISwitch接口,说明Light类必需要去实现接口中所有方法。
反过来说,Light类实现了ISwitch接口,说明Light类中一定有接口中的方法。

  • 接口表示:接口表示:...(类)具有...(接口)的功能。比如:灯具有开关的功能。

接口与抽象类的区别

接口和抽象类的功能有很多相似处:

  • 都可以定义一组函数声明。
  • 都是用来被继承或实现的。
  • 都要求类必须要实现其中所有的方法申明。

但他们区别是:一个是类,一个是接口。

  • 一个类只能继承一个父类;但可以实现多个接口。
  • 抽象类里面还可以有一些具体的函数、属性、事件等;但接口里只有函数声明。
  • 从编程思想上讲,继承类表示:...(子类)是...(父类);接口表示:...(类)具有...(接口)的功能。

    // 电器类
    class Electronic
    {
      // 接通电源
      public void Power()
      {
      }
    }
    // 灯是电器,具有开关的功能
    class Light : Electronic, ISwitch // 类与接口之间用,分开
    {
      // 亮度
      public int Brightness { get; set;}
    
      // 这里实现了接口中的Open方法
      public void Open()
      {
          Brightness = 10;
      }
    
      // 这里实现了接口中的Close方法
      public void Close()
      {
          Brightness = 0;
      }
    }
    

接口数据类型

  • 所有数据类型都可用来申明变量,接口也不例外。
  • 实现了接口的实例可以赋值给该接口的变量。
  • 使用接口变量,能调用接口中定义的函数。
    Light light = new Light();
    ISwitch s = light;
    s.Open(); // OK: ISwitch中有Open方法,所以可以调用。
    // s.Power(); // ERROR: 虽然s所代表的实例light有Power的方法,但ISwitch类型的变量只能调用这个接口中定义了的方法。
    

实现多个接口

  • 一个类只能有一个父类,但是可以实现多个接口。
  • 多接口中定义了同一个功能的情况。
  • 显式现实多接口。
    // 定义接口IA
    interface IA
    {
      void Fun();
      void FunA();
    }
    // 定义接口IB。IA、IB中都定义了函数Fun。
    interface IB
    {
      void Fun();
      void FunB();
    }
    // MyClass实现了多个接口
    class MyClass : IA, IB // 接口之间用,分开
    {
      // 同时实现IA和IB中Fun函数
      public void Fun()
      {
          Console.WriteLine("Fun");
      }
      public void FunA()
      {
          Console.WriteLine("FunA");
      }
      public void FunB()
      {
          Console.WriteLine("FunB");
      }
    }
    class Program
    {
      public static void Main()
      {
          MyClass mc = new MyClass();
          IA a = mc;
          IB b = mc;
          a.Fun(); // 输出:Fun
          b.Fun(); // 输出:Fun
      }
    }
    

显示实现接口方法

  • 上例中MyClass中的Fun函数,同时实现IAIB两个接口的要求。
  • 如果希望IAIB两个接口的Fun函数有不同的实现,可以显示实现接口方法。
    // 定义接口IA
    interface IA
    {
      void Fun();
      void FunA();
    }
    // 定义接口IB。IA、IB中都定义了函数Fun。
    interface IB
    {
      void Fun();
      void FunB();
    }
    // MyClass实现了多个接口
    class MyClass : IA, IB
    {
      // 实现了IA中的Fun函数
      public void IA.Fun()
      {
          Console.WriteLine("IA.Fun");
      }
      // 实现了IB中的Fun函数
      public void IB.Fun()
      {
          Console.WriteLine("IA.Fun");
      }
      public void FunA()
      {
          Console.WriteLine("FunA");
      }
      public void FunB()
      {
          Console.WriteLine("FunB");
      }
    }
    class Program
    {
      public static void Main()
      {
          MyClass mc = new MyClass();
          IA a = mc;
          IB b = mc;
          a.Fun(); // 输出:IA.Fun
          b.Fun(); // 输出:IB.Fun
      }
    }
    

高级运用(稍后补充)

有一个人叫李康,可以把李康赋值给程序员类型的变量,也可以把李康赋值给一个老师类型的变量。这时这两个变量指代的是同一个人,但是这两个变量所代表的身份类型不一样。

// 稍后补充

总结

  • 接口的用法有两种:让类去实现;做为一种数据类型。

results matching ""

    No results matching ""