C#-11 接口

  • C#-11 接口已关闭评论
  • 243 次浏览
  • A+
所属分类:.NET技术
摘要

接口是指定一组函数成员而不实现它们的引用类型。Array类有一个静态方法Sort(),可以排序元素。


一 什么是接口

接口是指定一组函数成员而不实现它们的引用类型。

class Program {     static void FlyFunc(IFly obj)      {         obj.Fly();     }      static void Main(string[] args)     {         var bird = new Bird();         var butterfly = new Butterfly();         FlyFunc(bird);         FlyFunc(butterfly);         Console.Read();     } }  //声明一个IFly接口 interface IFly {     void Fly(); }  class Bird : IFly {     public void Fly()     {         Console.WriteLine("Bird Fly");     } }  class Butterfly : IFly {     public void Fly()     {         Console.WriteLine("Butterfly Fly");     } }

二 使用IComparable接口的示例

Array类有一个静态方法Sort(),可以排序元素。

var array = new int[] { 50, 15, 59, 88, 14 }; Array.Sort(array); foreach (var item in array)     Console.Write($"{item} ");  //输出 14 15 50 59 88

Array类的Sort方法倚赖于IComparable接口,它声明在BCL中,包含唯一的方法CompareTo。

.NET文档中描述了CompareTo方法的作用,在调用CompareTo方法时,它应该返回以下几个值:

  • 负数值:当前对象小于参数对象;
  • 正数值:当前对象大于参数对象;
  • 零:两个对象在比较时相等;

Sort使用的算法倚赖于元素的CompareTo方法来决定两个元素的次序。

class Program {     static void Main(string[] args)     {         var myInt = new int[] { 10, 20, 1, 5, 50 };         var mcArr = new MyClass[5];         for (int i = 0; i < 5; i++)         {             mcArr[i] = new MyClass() { TheValue = myInt[i] };         }         foreach (var item in mcArr)         {             Console.Write($"{item.TheValue} ");         }         Console.WriteLine();         Array.Sort(mcArr);  //排序         foreach (var item in mcArr)         {             Console.Write($"{item.TheValue} ");         }         Console.ReadLine();         //输出: 10 20 1 5 50                 1 5 10 20 50     } }  //自定义的MyClass类,实现IComparable接口 class MyClass : IComparable {     public int TheValue { get; set; }      public int CompareTo(object obj)     {         var mc = (MyClass)obj;         if (this.TheValue < mc.TheValue) return -1;         if (this.TheValue > mc.TheValue) return 1;         return 0;     } }

 三 声明接口

接口声明不能包含数据成员和静态成员。

接口声明只能包含以下类型的非静态成员函数的声明:

  • 方法
  • 属性
  • 事件
  • 索引器

这些函数成员的声明不能包含任何实现代码,而在每一个成员声明的主体后必须使用分号。

按照惯例,接口名称以大写 I 开头,比如 ISaveable。

与类和结构一样,接口声明还可以分隔成分部接口声明。

接口声明可以有任何的访问修饰符,public、protected、internal、private。

接口的成员是隐式public的,不允许有任何修饰符,包括public。

四 实现接口

只有类和结构才能实现接口。

要实现接口,类和结构必须:

  • 在基类列表中包括接口名称
  • 为每一个接口成员提供实现
//声明接口
interface
IMyInterface { int ID { get; set; } void Method(string s); } //实现接口 class MyInterface : IMyInterface { public int ID { get; set; } public void Method(string s) { Console.WriteLine(s); } }

类和结构可以实现任意数量的接口。

interface IDataRetrieve {     int GetData(); }  interface IDataStore {     void SetData(int x); }  class MyData : IDataRetrieve, IDataStore {     int Mem1;     public int GetData()     {         return Mem1;     }      public void SetData(int x)     {         Mem1 = x;     } }  static void Main(string[] args) {     var myData = new MyData();     myData.SetData(5);     Console.WriteLine($"data is : {myData.GetData()}"); }

五 实现具有重复成员的接口

由于类可以实现任意数量的接口,有可能两个或多个接口成员都有相同的签名和返回类型。

这种情况下,类可以实现单个成员满足所有包含重复成员的接口。

interface IIfc1  {     void PrintOut(string s); }  interface IIfc2 {     void PrintOut(string s); }  class MyClass : IIfc1, IIfc2    //实现两个接口 {     void PrintOut(string s)  //两个接口的单一实现     {         Console.WriteLine(s);     } }

六 显示接口成员实现

如果希望为每一个接口分离实现,可以通过创建显示接口成员实现。

class MyClass : IIfc1, IIfc2    //实现两个接口 {     void IIfc1.PrintOut(string s)  //显示实现IIfc1     {         Console.WriteLine($"IIfc1 : {s}");     }      void IIfc2.PrintOut(string s)  //显示实现IIfc2     {         Console.WriteLine($"IIfc2 : {s}");     } }

七 派生成员作为实现

实现接口的类可以从它的基类继承实现的代码

interface IIfc1  {     void PrintOut(string s); }  interface IIfc2 {     void PrintOut(string s); }  class MyClass : IIfc1, IIfc2    //实现两个接口 {     void IIfc1.PrintOut(string s)  //显示实现IIfc1     {         Console.WriteLine($"IIfc1 : {s}");     }      void IIfc2.PrintOut(string s)  //显示实现IIfc2     {         Console.WriteLine($"IIfc2 : {s}");     } }  class MyDerivedClass : MyClass  { }  static void Main(string[] args) {     var myDericed = new MyDerivedClass();     ((IIfc1)myDericed).PrintOut("111");     ((IIfc2)myDericed).PrintOut("222");     Console.Read(); }