接口
- 接口使用示例(IComparable)
- Array.Sort可以排序预定义类型的数组,对自定义类型排序会抛出异常
- 可以实现IComparable接口中的CompareTo方法后再使用排序
- IComparable接口声明在BCL中,包含唯一的方法CompareTo
-
public interface IComparable { // interface为接口定义的关键字 int CompareTo(object obj); // this > obj返回+,<-,=0 }
- 实现接口
- 在基类列表后面列出接口名称
- 必须为接口的每一个成员提供实现
- 要使用Sort,如果仅声明CompareTo方法是不够的,还需要实现IComparable接口
- 声明接口
- 重要事项
- 接口声明不能包含以下成员:
- 数据成员
- 静态成员
- 接口声明只能包含如下类型的非静态成员函数的声明:
- 方法
- 属性
- 事件
- 索引器
- 这些函数成员的声明不能包含任何实现代码,而在每一个成员声明的主体后使用分号
- 按照惯例,接口名称必须以大写的I开始
- 类似于分部类,接口也可以分隔成分部接口声明
- 接口声明不能包含以下成员:
- 接口的访问性和接口成员的访问性
- 接口声明可以有任何的访问修饰符public、protected、internal或private
- 接口成员是隐式public的,不允许有任何访问修饰符包括public
- 在类实现接口的方法的时候要显式写出public
- 在类通过显式接口成员实现(即后面介绍的
接口名.方法名
)的时候不能写public
- 重要事项
- 实现接口
- 重要事项
- 它必须实现接口的所有成员
- 如果类从基类继承并实现了接口,基类列表中的基类名称必须放在接口之前
- 重要事项
- 接口是引用类型
- 不能通过类对象的成员访问接口,但是可以把对象强转为接口类型来获取指向接口的引用
- 可以通过点号调用接口的方法
- 接口和as运算符
- 如果类对象没有实现接口,强转会抛异常
- 使用as运算符可以避免这个问题
- 如果实现了接口则返回接口的引用
- 没有实现接口则返回null而不是抛异常
- 类对象引用 as 接口名
- 实现多个接口
- 类可以实现任意数量的接口
- 基类与接口、接口与接口之间用逗号分隔
- 实现具有重复成员的接口
- 如果一个类实现了多个接口并且其中一些接口有相同签名和返回类型的成员
- 那么类可以实现单个成员来满足所有包含重复成员的接口
- 如果参数列表不同
- 可以都实现,作为方法重载
- 如果参数列表相同但是返回类型不同
- 会报错,只能使用后面要讲的显式接口成员实现
- 如果一个类实现了多个接口并且其中一些接口有相同签名和返回类型的成员
- 多个接口的引用
- 对象引用可以强转为接口的引用,如果实现了多个接口,可以获取每个接口的独立引用
- 派生成员作为实现
- 实现接口的类可以从它的基类继承实现的代码,即便基类没有实现该接口
- 显式接口成员实现
- 单个类可以实现多个接口需要的成员,如6、7部分
- 也可以通过显式接口成员实现的方式为每一个接口分离实现,与显式接口成员实现相对的叫做类级别实现
- 使用限定接口名称来声明,由
接口名称.成员名称
来实现 - 可以对多个接口中的重复成员提供不同的实现
- 类级别实现与显式接口成员实现(此处简称接口实现)的区别
- 类级别实现,方法是属于类的,而接口实现是属于接口的
- 类级别实现中,接口方法会指向类级别实现,而接口实现是包含了自己的代码
- 通过类级别实现,可以通过对象引用调用,可以在类内部直接调用,也可以通过接口引用去调用;而接口实现只能通过接口引用去调用
-
public interface II { int Fun(); } class Test : II { int II.Fun() { return 123; } public int Fun() { return 456; } } Test t = new Test(); System.Console.WriteLine(t.Fun()); // 类级别实现,输出456 II i = t as II; System.Console.WriteLine(i.Fun()); // 显式接口成员实现,输出123
- 如果有显式接口成员实现,类级别是允许的,但不是必须的,有以下三种实现场景
- 类级别实现
- 显式接口成员实现
- 类级别和显式接口成员实现
- 访问显式接口成员只能通过接口引用访问
- 接口可以继承接口
- 接口本身可以从一个或多个接口继承
- 接口可以多继承
- 接口本身可以继承其他接口
- 结果接口包含它声明的所有接口和所有基接口的成员