接口
接口的定义
- 接口是一种自定义数据类型。所以写在
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
接口也可以去定义Open
、Close
方法呀,为什么一定要实现这个接口呢?
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
函数,同时实现IA
和IB
两个接口的要求。 - 如果希望
IA
和IB
两个接口的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 } }
高级运用(稍后补充)
有一个人叫李康,可以把李康赋值给程序员类型的变量,也可以把李康赋值给一个老师类型的变量。这时这两个变量指代的是同一个人,但是这两个变量所代表的身份类型不一样。
// 稍后补充
总结
- 接口的用法有两种:让类去实现;做为一种数据类型。