文章目录
- 16.1 什么是接口
- 16.2 声明接口
- 16.3 实现接口
- 16.4 接口是引用类型
- 16.5 接口和 as 运算符
- 16.6 实现多个接口
- 16.7 实现具有重复成员的接口
- 16.8 多个接口的引用(*)
- 16.9 派生成员作为实现(*)
- 16.10 显示接口成员实现
- 16.11 接口可以继承接口
- 16.12 不同类实现一个接口的示例(*)
16.1 什么是接口
接口是声明一组函数成员而不进行实现的引用类型,只能用类和结构来实现接口。
使用 IComparable 接口的示例
Array 类的 Sort 方法依赖于 IComparable 接口,其声明在 BCL 中,只包含唯一的 CompareTo 方法。图 16.1 中灰色表示该方法目前未实现。
调用 CompareTo 方法时,应该返回如下值:
- 负数:当前对象 < 参数对象。
- 正数:当前对象 > 参数对象。
- 0:两个对象相等。
为自定义类实现 IComparable 接口后,就可以使用 Array.Sort 方法进行排序:
16.2 声明接口
- 接口声明不能包含以下成员:
- 数据成员。
- 静态成员。
- 接口声明只能包含如下类型的非静态成员:
- 方法。
- 属性。
- 事件。
- 索引器。
- 函数声明不能包含任何实现代码,而是使用分号代替函数主体。
- 接口名称必须从大写的 I 开始。
- 可以声明分部接口。
- 接口和接口成员的访问性有一些不同:
- 接口声明可以有任何的访问修饰符。
- 接口成员是隐式 public,不能有任何访问修饰符。
16.3 实现接口
要实现接口,类和结构必须:
- 在基类列表中包含接口名称。
- 为每一个接口成员提供实现。
重要事项如下:
- 必须实现接口的所有成员。
- 基类名称必须放在所有接口之前。
16.4 接口是引用类型
不能通过类对象的成员访问接口,只能通过将类对象引用强制转换为接口类型来获取接口引用。注意:接口引用不能调用类中不属于接口的其他成员。
16.5 接口和 as 运算符
如果尝试将类对象引用强制转换为类未实现的接口引用,则会抛出异常。使用 as 运算符可以避免抛出异常:
- 如果实现了类接口,则 as 返回指向接口的引用。
- 如果未实现接口,则 as 返回 null,而不抛出异常。
16.6 实现多个接口
- 类或结构可以实现任意数量的接口
- 所有实现的接口必须列在基类列表中,以逗号分隔(在基类名称之后,如果有的话)。
16.7 实现具有重复成员的接口
如果一个类实现了多个接口,并且其中一些接口具有相同的成员,则类可以实现单个成员来同时匹配所有重复成员的接口。
16.8 多个接口的引用(*)
16.9 派生成员作为实现(*)
16.10 显示接口成员实现
可以创建显示接口以实现相同接口的分离:
- 使用限定接口名称声明。
- 限定接口名称的声明如下:
因此,对于成员函数而言,有如下三种实现方法:
- 类级别实现(不依赖接口,专门提供给类对象调用)。
- 显示接口成员实现(依赖接口,专门提供给接口调用)。
- 类级别和显示接口成员实现(类和接口都能调用)。
下面这个例子包含了两个显示接口成员实现,而没有类级别的实现。即,只能通过接口引用调用函数 PrintOut,而不能使用类对象调用:。mc.PrintOut()
访问显示接口成员实现
显示接口成员实现只能通过接口来访问:
16.11 接口可以继承接口
- 类在基类列表中只能有一个类名;而接口可以有任意多个接口。
- 列表中的接口本身也可以继承其他接口。
- 继承后的接口包含自己的成员和所有继承接口的成员。