第11章接口和结构 ■11.1接口 接口是抽象成员的集合,这些抽象成员可以是抽象方法、属性、 索引器、事件等。接口是实现多继承的工具。实际上,接口是 些实现特定功能的抽象成员的集合。一个类可以继承多个接口, 从而获得多个行为的描述,将它们组合成新的功能并在类中实现 1111定义接口 定义接口的格式为: 特性接口修饰符 interface接口名:基接口列表 接口体 接口体的声明可以包括: 接口方法声明;接口属性声明;接口事件声明;接口索引器声明
第11章 接口和结构 接口是抽象成员的集合,这些抽象成员可以是抽象方法、属性、 索引器、事件等。接口是实现多继承的工具。实际上,接口是一 些实现特定功能的抽象成员的集合。一个类可以继承多个接口, 从而获得多个行为的描述,将它们组合成新的功能并在类中实现。 11.1.1 定义接口 定义接口的格式为: 特性 接口修饰符 interface 接口名:基接口列表 { 接口体 } 接口体的声明可以包括: 接口方法声明;接口属性声明;接口事件声明;接口索引器声明 ◼ 11.1 接口
11.1接口 ■11.1.2实现接口 接口可以由类来实现,也可以由结构来实现。所谓实现接 口,就是继承它们并且在被继承方法、属性、索引器和事件中填 入体现所需行为的代码 用类实现接口的格式为 class类名:[基类],接口,接口,…,接口 //成员定义部分 基类名在接口名之前,基类至多只能有一个,但可以继承零个或 多个接口
11.1 接口 接口可以由类来实现,也可以由结构来实现。所谓实现接 口,就是继承它们并且在被继承方法、属性、索引器和事件中填 入体现所需行为的代码。 用类实现接口的格式为: class 类名 : [基类],接口,接口,…,接口 { …… // 成员定义部分 } 基类名在接口名之前,基类至多只能有一个,但可以继承零个或 多个接口。 ◼ 11.1.2 实现接口
11.1.3接口对象 接口中包含的是抽象的方法,接口不可能有真正意义上的对象 但是接口本质上是一组协议,这一点和产生多态对象的基类的 作用和地位十分相似,实际上,接口也可以声明对象,而用实 现该接口的派生类的构造函数创建对象,本书把这样的接口称 为接口对象。利用接口对象可以将实现该接口的派生类作为 个整体来处理
11.1.3 接口对象 接口中包含的是抽象的方法,接口不可能有真正意义上的对象。 但是接口本质上是一组协议,这一点和产生多态对象的基类的 作用和地位十分相似,实际上,接口也可以声明对象,而用实 现该接口的派生类的构造函数创建对象,本书把这样的接口称 为接口对象。利用接口对象可以将实现该接口的派生类作为一 个整体来处理
11.4显式接口成员实现 集,, 多继承接口以及隐式继承基接口都有可能使得派生类或者派生接 口中出现相同签名的成员,同时也可能出现并不需要的成员。C# 接口可以定义显式接口成员实现来避免这些问题 显式接口成员使用完全限定名称作为该成员的标识符。完全限定 名称是用接口名和接口成员名连接而成的,但是这个接口名必须 是出现在基接口列表中的显式基接口。实现显式接口成员时应该 注意: 口显式接口成员实现访问控制权限是 private,所以不能用其它 访问控制符; 口显式接口成员实现不能用 abstract、 virtual、 override或 static修饰符: 调用显式接口成员实现时,必须使用接口对象,而不是类对象 口也可以用强制类型转换访问显式接口成员实现
1.1.4 显式接口成员实现 多继承接口以及隐式继承基接口都有可能使得派生类或者派生接 口中出现相同签名的成员,同时也可能出现并不需要的成员。C# 接口可以定义显式接口成员实现来避免这些问题。 显式接口成员使用完全限定名称作为该成员的标识符。完全限定 名称是用接口名和接口成员名连接而成的,但是这个接口名必须 是出现在基接口列表中的显式基接口。实现显式接口成员时应该 注意: ❑ 显式接口成员实现访问控制权限是private,所以不能用其它 访问控制符; ❑ 显式接口成员实现不能用abstract、virtual、override或 static修饰符; ❑ 调用显式接口成员实现时,必须使用接口对象,而不是类对象; ❑ 也可以用强制类型转换访问显式接口成员实现
112结构 结构与类类型相似,结构也可以拥有字段、常数、属性、索引 器、方法、事件、运算符和嵌套类型等各种成员;结构也可以 实现接口 但是,结构和类之间有本质的差别:结构是值类型,存放在栈 中,而类是引用类型,存放在堆中,由此导致了不少语法上的 不同,和应用场合的不同
11.2 结构 结构与类类型相似,结构也可以拥有字段、常数、属性、索引 器、方法、事件、运算符和嵌套类型等各种成员;结构也可以 实现接口。 但是,结构和类之间有本质的差别:结构是值类型,存放在栈 中,而类是引用类型,存放在堆中,由此导致了不少语法上的 不同,和应用场合的不同
1121结构的声明 声明结构的格式如下: 特性修饰符 struct结构名:基接口列表 //结构体 其中: 口特性( attribute)为可选项 口修饰符也是可选项,允许使用的修饰符有:new、 public internal、 protected和 private; 口冒号和基接口列表表示继承基接口,基接口之间用逗号分隔,接 口的继承是可选的。 结构不能继承类,虽然结构隐含地继承 Object类,结构也不能继承另 个结构,而且不能作为一个类的基。但是,结构可实现接口,而且 实现方式与类实现接口的方式完全相同
11.2.1 结构的声明 声明结构的格式如下: 特性 修饰符 struct 结构名 : 基接口列表 { … … //结构体 } 其中: ❑ 特性(attribute)为可选项; ❑ 修饰 符也 是 可 选项 , 允许 使 用的 修 饰符 有 :new、public、 internal、 protected和 private; ❑ 冒号和基接口列表表示继承基接口,基接口之间用逗号分隔,接 口的继承是可选的。 结构不能继承类,虽然结构隐含地继承Object类,结构也不能继承另 一个结构,而且不能作为一个类的基。但是,结构可实现接口,而且 实现方式与类实现接口的方式完全相同
1122结构的实例化 创建结构对象的格式如下: 结构名结构实例=new结构构造函数; 但是结构的实例化有特殊性: 1)结构的构造函数:结构不能声明默认的构造函数,或者说, 不能声明无参的构造函数,系统会自动地给出无参的构造函数, 结构中自定义的构造函数必须带参数; 2)结构成员不能有初始值设定项。总是由默认构造函数将结构 成员初始化为它们的默认值; 3)使用new运算符创建结构对象时,将调用适当的构造函数; 4)结构的实例化可以不使用new运算符,其效果是所有字段被初 始化之前,将保持未赋值状态,且对象不可用
11.2.2 结构的实例化 创建结构对象的格式如下: 结构名 结构实例 = new 结构构造函数; 但是结构的实例化有特殊性: 1) 结构的构造函数:结构不能声明默认的构造函数,或者说, 不能声明无参的构造函数,系统会自动地给出无参的构造函数, 结构中自定义的构造函数必须带参数; 2) 结构成员不能有初始值设定项。总是由默认构造函数将结构 成员初始化为它们的默认值; 3) 使用new运算符创建结构对象时,将调用适当的构造函数; 4) 结构的实例化可以不使用new运算符,其效果是所有字段被初 始化之前,将保持未赋值状态,且对象不可用
1122结构的实例化 创建结构对象的格式如下: 结构名结构实例=new结构构造函数; 但是结构的实例化有特殊性: 1)结构的构造函数:结构不能声明默认的构造函数,或者说, 不能声明无参的构造函数,系统会自动地给出无参的构造函数, 结构中自定义的构造函数必须带参数; 2)结构成员不能有初始值设定项。总是由默认构造函数将结构 成员初始化为它们的默认值; 3)使用new运算符创建结构对象时,将调用适当的构造函数; 4)结构的实例化可以不使用new运算符,其效果是所有字段被初 始化之前,将保持未赋值状态,且对象不可用
11.2.2 结构的实例化 创建结构对象的格式如下: 结构名 结构实例 = new 结构构造函数; 但是结构的实例化有特殊性: 1) 结构的构造函数:结构不能声明默认的构造函数,或者说, 不能声明无参的构造函数,系统会自动地给出无参的构造函数, 结构中自定义的构造函数必须带参数; 2) 结构成员不能有初始值设定项。总是由默认构造函数将结构 成员初始化为它们的默认值; 3) 使用new运算符创建结构对象时,将调用适当的构造函数; 4) 结构的实例化可以不使用new运算符,其效果是所有字段被初 始化之前,将保持未赋值状态,且对象不可用
11.23结构的应用 结构的内容和结构名一起存放在栈中,这带来了二重性:访问栈 中的内容比访问堆中的内容简捷高效;但是如果栈中内容过多过 大时,效率反而降低。所以结构特别适合于定义简单的数据结构
11.2.3 结构的应用 结构的内容和结构名一起存放在栈中,这带来了二重性:访问栈 中的内容比访问堆中的内容简捷高效;但是如果栈中内容过多过 大时,效率反而降低。所以结构特别适合于定义简单的数据结构
1124结构和类的比较 1.类型、赋值和参数传递: 2.构造函数、析构函数、实例化和字段值: 3.继承和可访问性: 4.装箱和拆箱: 5.ths的意义:
11.2.4 结构和类的比较 1.类型、赋值和参数传递: 2.构造函数、析构函数、实例化和字段值: 3.继承和可访问性: 4.装箱和拆箱: 5. this的意义: