c# 2015 & 2017 视频教程|xin3721自学网c#入门经典视频教程https://www.xin3721.com/eschool/CSharpxin3721/
一 什么是接口
接口是指定一组函数成员而不实现它们的引用类型。
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(); }