Ch08.继承和多态
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
8.2.2 访问关键字this和base
• this关键字引用类的当前实例。静态成员方法中不能使 用this关键字。this关键字只能在实例构造函数、实例 方法或实例访问器中使用 • base关键字用于从派生类中访问基类的成员:
– 指定创建派生类实例时应调用的基类构造函数 – 调用基类上已被其他方法重写的方法
8.1.2 继承的类型
• 实现继承表示一个类型派生于一个基类型,派生类具有基类的所 有非私有(非private)数据和行为。在实现继承中,派生类型的 每个方法采用基类型的实现代码,除非在派生类型的定义中指定 重写该方法的实现代码。实现继承一般用于增加现有类型的功能 ,或许多相关的类型共享一组重要的公共功能的场合 • 接口继承表示一个类型实现若干接口,接口仅包含方法的签名, 故接口继承不继承任何实现代码。接口继承一般用于指定该类型 具有某类可用的特性。例如,如果指定类型从接口 System.IDisposable中派生,并在该类中实现IDisposable接口的清 理资源的方法Dispose(),则可以通过共通的机制,调用该方法以 清理资源。由于清理资源的方式特定于不同的类型,故在接口中 定义通用的实现代码是没有意义的。接口即契约,类型派生于接 口,即保证该类提供该接口规定的功能
– 单选题 – 填空题 – 思考题
8.2 派生类
• 在声明派生类时,在类名称后放置一个冒号,然后在 冒号后指定要从中继承的类(即基类) • 派生类可以访问基类的非private成员,但是派生类的属 性和方法不能直接访问基类的private成员。派生类可以 影响基类private 成员的状态改变,但只能通过基类提 供并由派生类继承的非private 的属性和方法来改变 • C#不支持多重继承,即一个派生类只能继承于一个基 类 • 【例8.2】派生类示例:创建基类Person,包含2个数据 】 成员name和age、1个具有2个参数的构造函数;创建派 生类Student,包含1个数据成员studentID、1个具有3个 参数的派生类构造函数并用“:base”调用基类构造函 数
– [特性] – [接口修饰符][partial] interface 接口名 [类型形参] [: 基接口[类 型形参约束]] – { – 接口体 – }[;]
• 【例8.7】接口实现示例 【例8.8】两个接口实现示例 】 】
实验和习题
• 实验 5-3~5-6 • 教程 例8-1~例8-9 • 第8章 继承和多态
第8章 继承和多态
•继承和多态的基本概念 •派生类的声明和使用 •访问关键字this和base •虚方法、重写方法和隐藏方法 •抽象类和抽象方法 •密封类和密封方法 •接口的声明和使用
8.1 继承和多态的基本概念
• 继承允许重用现有类(基类,亦称超类、父类)去创 建新类(子类,亦称派生类)的过程。子类将获取基 类的所有非私有数据和行为,子类可以定义其他数据 或行为 • 派生类具有基类的所有非私有数据和行为以及新类自 己定义的所有其他数据或行为,即子类具有两个有效 类型:子类的类型和它继承的基类的类型 • 对象可以表示多个类型的能力称为多态性 • 【例8.1】多态性示例 】
Biblioteka Baidu
8.5 接口
• 一个接口定义一个协定。接口本身不提供它所定义的 成员的实现,接口只指定实现该接口的类或结构必须 提供的成员,继承接口的任何非抽象类型都必须实现 接口的所有成员。 • 接口类似于抽象基类,接口不能实例化。接口中声明 的所有成员隐式地为public和abstract。接口可以包含事 件、索引器、方法和属性,但接口不能包含字段 • 接口声明的基本形式如下:
• 不能从静态方法中使用 base 关键字,base关键字只能 在实例构造函数、实例方法或实例访问器中使用 • 【例8.3】访问关键字this和base示例 】
8.2.3 虚方法、重写方法和隐藏方法
• 在基类中使用关键字virtual定义虚方法(virtual method);然后派 生类中使用关键字override来重写方法(override method),或使 用关键字new来覆盖方法(隐藏方法)。 • 重写方法用相同的签名重写所继承的虚方法。虚方法声明用于引 入新方法,而重写方法或隐藏方法声明则用于使现有的继承虚方 法专用化(通过提供该方法的新实现) • 调用虚方法时,将首先检查该对象的运行时类型,并调用派生类 中的该重写成员,如果没有派生类重写该成员,则调用其原始成 员 • 默认情况下,C#方法是非虚拟的。不能重写非虚方法 • 除了类方法,还可以使用virtual关键字修饰的其他类成员以定义 虚成员,包括:属性、索引器或事件声明。虚拟成员的实现可在 派生类中使用关键字override来重写;或使用关键字new来覆盖 • 【例8.4】虚方法、重写方法和隐藏方法示例 】
• 【例8.5】抽象类示例 】 • 抽象类中通过将关键字 abstract 添加到实例方法的返回类型的前 面可以定义抽象方法(abstract method) • 【例8.6】抽象方法示例 】
8.4 密封类和密封方法
• 通过将关键字 sealed 置于关键字 class 的前面,可以将 类声明为密封类(sealed class)。密封类不能用作基类 。因此,它也不能是抽象类。 • 密封类主要用于防止非有意的派生。由于密封类从不 用作基类,所以调用密封类成员的效率可能会更高些 • 当实例方法声明包含 sealed 修饰符时,称该方法为密 封方法(sealed method)。如果实例方法声明包含 sealed 修饰符,则它必须也包含 override 修饰符。使用 sealed 修饰符可以防止派生类进一步重写该方法 • 在许多情况下,可以把密封类和密封方法看作是与抽 象类和抽象方法的对立。把类或方法声明为抽象,表 示该类或方法必须被重写或继承;而把类或方法声明 为密封,表示该类或方法不能重写或继承
8.3 抽象类和抽象方法
• 将关键字 abstract 置于关键字 class 的前面可以将类声明为抽象类 。抽象类不能实例化,抽象类一般用于提供多个派生类可共享的 基类的公共定义。例如,类库可以定义一个包含基本功能的抽象 类,并要求程序员使用该库通过创建派生类来提供自己的类实现 • 抽象类与非抽象类相比,具有下列特征:
– 抽象类不能直接实例化,对抽象类使用new运算符会导致编译时错误。可以定 义抽象类型的变量,但其值必须为 null,或者是其派生的非抽象类的实例的 引用 – 允许(但不要求)抽象类包含抽象成员 – 抽象类不能被密封 – 当从抽象类派生非抽象类时,这些非抽象类必须实现所继承的所有抽象成员 ,从而重写那些抽象成员