第8章.继承和多态.ppt_第1页
第8章.继承和多态.ppt_第2页
第8章.继承和多态.ppt_第3页
第8章.继承和多态.ppt_第4页
第8章.继承和多态.ppt_第5页
已阅读5页,还剩42页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第8章继承和多态 继承和多态的基本概念派生类的声明和使用访问关键字this和base虚方法 重写方法和隐藏方法抽象类和抽象方法密封类和密封方法接口的声明和使用 8 1继承和多态的基本概念 继承允许重用现有类 基类 亦称超类 父类 去创建新类 子类 亦称派生类 的过程 子类将获取基类的所有非私有数据和行为 子类可以定义其他数据或行为派生类具有基类的所有非私有数据和行为以及新类自己定义的所有其他数据或行为 即子类具有两个有效类型 子类的类型和它继承的基类的类型对象可以表示多个类型的能力称为多态性 例8 1 多态性示例 8 2派生类 在声明派生类时 在类名称后放置一个冒号 然后在冒号后指定要从中继承的类 即基类 派生类可以访问基类的非private成员 但是派生类的属性和方法不能直接访问基类的private成员 派生类可以影响基类private成员的状态改变 但只能通过基类提供并由派生类继承的非private的属性和方法来改变C 不支持多重继承 即一个派生类只能继承于一个基类 继承 父类 子类 继承也可以说是一种包含关系 继承类的继承性类的继承性是指一个类定义既可以具有其他类的数据成员 属性成员 方法成员等 也可以使其他类具有自己的数据成员 属性成员 方法成员等 在类的继承中 被继承的类叫基类或父类 继承的类叫派生类或子类 人类的继承关系 一般人类 Person 具有年龄 性别 姓名等特征学生 也是人 除了具有一般人的特征之外 还具有学号 就读学校 入学时间 考试成绩等特征 例8 2 派生类示例 创建基类Person 包含2个数据成员name和age 1个具有2个参数的构造函数 创建派生类Student 包含1个数据成员studentID 1个具有3个参数的派生类构造函数并用 base 调用基类构造函数 Person 一般人 Student 学生类 Name LiuLiGender F Age 21 Name WangDanGender M Age 42 Name LuSanGender F Age 38 Name Zhang3Gender F Age 18Score 88 0 Name Li4Gender M Age 17Score 92 0 父类 子类 练习 辨认以下类别的父子关系 1汽车 交通工具 飞机2运动用品 球类 篮球 足球练习 列举出一个 汽车 类的子类 不使用继承设计类 人类和学生类 classPerson publicintage publicstringname publicvoidsleep publicvoideat classStudent publicintage publicstringname publicvoidsleep publicvoideat publicvoidstudy 成员需要重新定义 使用继承机制可以避免相同成员的重复定义 定义派生类1 派生类定义格式派生类通常定义的语法格式为 类修饰符class类名 基类 类体 指定基类 父类 基类定义如下 publicclassStudent publicstringid publicstringname publicstringsex publicbyteage publicstringShow return 学号 id 姓名 name n性别 sex 年龄 age 派生类定义如下 publicclassStudent 1 Student publicbytescore1 score2 publicuintTotal return uint score1 uint score2 publicfloatAverage return float score1 score2 2 例 使用继承的 学生类 定义 classPerson publicintage publicstringname publicvoidsleep publicvoideat classStudent Person publicintclassId 班别编号publicintscore 学生成绩publicvoidstudy 首先定义基类 包含共有的成员 Student类继承于Person类 派生类的对象自动拥有父类的成员 classPerson publicintage publicstringname publicvoidsleep publicvoideat classStudent Person publicintclassId 班别编号publicintscore 学生成绩publicvoidstudy Studentzhang3 newStudent zhang3 age 20 Student类型的对象的成员 agenamesleep eat classIdscorestudy 继承的成员 特有的成员 练习1 根据提示补充程序 usingSystem publicclassParentClass publicParentClass Console WriteLine ParentConstructor publicvoidprint Console WriteLine IamaParentClass publicclassChildClass public 子类的初始化 Console WriteLine ChildConstructor publicstaticvoidMain 调用Print方法 父子关系 调用父类的方法 基类在派生类初始化之前自动初始化 2 protected访问修饰符的作用根据面向对象程序设计封装性要求 类中的数据成员通常是不允许直接访问的 因此数据成员一般不使用public修饰符 而使用protected或private修饰符 使对数据成员的访问必须通过public的属性或方法实现 在类的继承中 作为基类的数据成员通常使用protected修饰符 而不使用private修饰符 因为如果在基类中使用private修饰符声明数据成员 则其成员将不允许派生类成员访问 而protected修饰符 既能保证数据成员不被直接访问 又允许其派生类成员访问 3 创建派生类对象基类与派生类定义完成后 用派生类声明的对象 将包含基类的成员 除了构造函数 因此 派生类对象可以直接访问基类成员 例如 Student 1subS newStudent 1 设置派生类继承的基类数据成员值subS SetStudent 2005001 张三 女 21 设置派生类自身数据成员值subS SetStudent 1 90 100 subS Show 调用派生类继承的基类方法 4 构造函数的调用在创建派生类对象时 调用构造函数的顺序是先调用基类构造函数 再调用派生类的构造函数 以完成为数据成员分配内存空间并进行初始化的工作 如果派生类的基类本身是另一个类的派生类 则构造函数的调用次序按由高到低顺序依次调用 例如 假设A类是B类的基类 B类是C类的基类 则创建C类对象时 调用构造函数的顺序为 先调用A类的构造函数 再调用B类的构造函数 最后调用C类的构造函数 密封类C 中有一种类叫密封类 密封类是不允许其他类继承的类 Convert类就是一个密封类 定义密封类需要使用sealed关键字 其格式为 访问修饰符sealedclass类名称 例如 publicsealedclassSealedClass publicstringmethod return 我是密封类 C 还允许将一个非密封类定义中的某个方法声明为密封方法 一旦方法被声明为密封方法 将不允许在派生类中重载该方法 关于派生类中重载基类方法 将在下节 多态性 中介绍 例如 publicclassSealedMethod publicsealedstringSMethod return 我是一个密封方法 usingSystem classAnimal protecteddoubleweight 0 publicvoidEat doublex weight x 0 5 if weight 100 weight 100 publicdoublegetWeight returnweight classDog Animal publicDog doublew weight w 0 8 publicvoidDrink doublex weight x 0 2 if weight 100 weight 100 classProgram publicstaticvoidMain Dogd newDog 80 Console WriteLine d getWeight d Eat 20 Console WriteLine d getWeight d Drink 80 Console WriteLine d getWeight d Eat 300 Console WriteLine d getWeight 8 2 2访问关键字this和base this关键字引用类的当前实例 静态成员方法中不能使用this关键字 this关键字只能在实例构造函数 实例方法或实例访问器中使用base关键字用于从派生类中访问基类的成员 指定创建派生类实例时应调用的基类构造函数调用基类上已被其他方法重写的方法不能从静态方法中使用base关键字 base关键字只能在实例构造函数 实例方法或实例访问器中使用 例8 3 访问关键字this和base示例 p151 向基类构造函数传递参数向基类构造函数传递参数 必须通过派生类的构造函数实现 其格式如下 public派生类构造函数名 形参列表 base 向基类构造函数传递的实参列表 base 是C 关键字 表示调用基类的有参构造函数 传递给基类构造函数的 实参列表 通常包含在派生类构造函数的 形参列表 中 多态性多态性概述在类的继承中 C 允许在基类与派生类中声明具有同名的方法 而且同名的方法可以有不同的代码 也就是说在基类与派生类的相同功能中可以有不同的具体实现 从而为解决同一问题提供多种途径 多态性就是指在程序运行时 执行的虽然是一个调用方法的语句 却可以根据派生类对象的类型不同完成方法的不同的具体实现 在C 中可以通过多种途径实现多态性 例 不同几何图形对象都需要计算面积的功能 getArea 方法 几何图形 长方形 圆 三角形 问题 有若干几何图形需要管理 有时需要统计这些图形的数据 比如求不同形状图形的面积 8 2 3虚方法 重写方法和隐藏方法 在基类中使用关键字virtual定义虚方法 virtualmethod 然后派生类中使用关键字override来重写方法 overridemethod 或使用关键字new来覆盖方法 隐藏方法 重写方法用相同的签名重写所继承的虚方法 虚方法声明用于引入新方法 而重写方法或隐藏方法声明则用于使现有的继承虚方法专用化 通过提供该方法的新实现 调用虚方法时 将首先检查该对象的运行时类型 并调用派生类中的该重写成员 如果没有派生类重写该成员 则调用其原始成员默认情况下 C 方法是非虚拟的 不能重写非虚方法除了类方法 还可以使用virtual关键字修饰的其他类成员以定义虚成员 包括 属性 索引器或事件声明 虚拟成员的实现可在派生类中使用关键字override来重写 或使用关键字new来覆盖 例8 4 虚方法 重写方法和隐藏方法示例 虚方法1 声明与基类同名的派生类方法在派生类中用new关键字声明与基类同名的方法的格式如下 publicnew方法名称 参数列表 2 声明虚方法基类中的声明格式 publicvirtual方法名称 参数列表 派生类中的声明格式 publicoverride方法名称 参数列表 virtual方法 当方法中包含virtual修饰符时 方法称为虚方法 否则 称为 非虚方法 非虚方法的执行功能是确定不变的虚方法的执行可以被派生类改变 重新定义此虚方法时 要求方法名 参数类型和返回类型完全一致 参数名可以不同 并加上override修饰符 不能用virtual修饰符 例 管理简单的计算机图形信息 包括长方形 圆形等 可以统计图形的面积 classShape charshapeType R C 约定图形的类型 长方形 圆形等 doublew 长方形的宽doubleh 长方形的高doubleradio 圆形的半径doublegetArea switch shapeType case A 长方形returnw h break case B 圆形return3 14 r r break 采用多分支语句分别执行不同的代码需要扩充不同的类型的时候较为麻烦 弊端 1 每一个对象占据同样大小的内存空间 对于小对象造成资源的浪费 2 增加类型时 工作量巨大 Shape图形类 x y 中心点坐标virtualgetArea Rect长方形类length width长宽overridegetArea Circle圆形类radius半径overridegetArea 虚函数 基类中使用virtual修饰 虚函数 派生类中的使用override修饰 usingSystem classShape 几何形状类 publicdoublex 0 y 0 publicvirtualdoublegetArea return0 0 计算面积 classRect Shape 长方形类 doublelength width 长宽publicRect doublel doublew length l width w publicoverridedoublegetArea returnlength width classCircle Shape 圆形类 doubleradius 半径publicCircle doubler radius r publicoverridedoublegetArea return3 1416 radius radius classHello publicstaticvoidMain Shape p newShape 4 p 0 newRect 1 5 2 0 p 1 newCircle 2 0 p 2 newRect 3 0 2 5 p 3 newRect 1 2 0 8 计算所有图形de面积doubleTotalArea 0 0 for inti 0 i 4 i TotalArea p i getArea Console WriteLine TotalArea 0 TotalArea 父类中用virtual修饰 子类中用override修饰 重写 classHello publicstaticvoidMain Shape p newShape 4 p 0 newRect 1 5 2 0 p 1 newCircle 2 0 p 2 newRect 3 0 2 5 p 3 newRect 1 2 0 8 计算所有图形总面积doubleTotalArea 0 0 for inti 0 i 4 i TotalArea p i getArea Console WriteLine TotalArea 0 TotalArea 子类对象可以隐式转换为父类对象 不同类型的对象可以使用相同的名字调用 并且调用正确的版本 usingSystem classShape 几何形状publicdoublex 0 y 0 PublicdoublegetArea return0 0 计算面积 classRect Shape 长方形doublelength width 长宽publicRect doublel doublew length l width w publicnewdoublegetArea returnlength width classCircle Shape 圆形doubleradius 半径publicCircle doubler radius r publicnewdoublegetArea return3 1416 radius radius 0 classHello publicstaticvoidMain Shape p newShape 4 p 0 newRect 1 5 2 0 p 1 newCircle 2 0 p 2 newRect 3 0 2 5 p 3 newRect 1 2 0 8 计算所有图形de面积doubleTotalArea 0 0 for inti 0 i 4 i TotalArea p i getArea Console WriteLine TotalArea 0 TotalArea 父类中不用virtual修饰 子类需要使用new修饰符 虚方法实例应用 趁热打铁 我们来解读书上153页的例8 4练习 如何通过虚方法实现计算机图形的周长的统计计算 长方形 圆 getgirth 方法 调用基类方法在派生类中声明与基类同名的方法 也叫方法重载 在派生类重载基类方法后 如果想调用基类的同名方法 可以使用base关键字 例如 假定基类与派生类都有一个无参数Show方法 则在派生类中调用基类Show方法的代码为 baseShow 调用基类Show方法 8 3抽象类和抽象方法 将关键字abstract置于关键字class的前面可以将类声明为抽象类 抽象类不能实例化 抽象类一般用于提供多个派生类可共享的基类的公共定义 例如 类库可以定义一个包含基本功能的抽象类 并要求程序员使用该库通过创建派生类来提供自己的类实现抽象类与非抽象类相比 具有下列特征 抽象类不能直接实例化 对抽象类使用new运算符会导致编译时错误 可以定义抽象类型的变量 但其值必须为null 或者是其派生的非抽象类的实例的引用允许 但不要求 抽象类包含抽象成员抽象类不能被密封当从抽象类派生非抽象类时 这些非抽象类必须实现所继承的所有抽象成员 从而重写那些抽象成员 例8 5 抽象类示例抽象类中通过将关键字abstract添加到实例方法的返回类型的前面可以定义抽象方法 abstractmethod 例8 6 抽象方法示例 抽象类与抽象方法为了实现多态 必须在基类中声明虚方法 但有时基类中声明的虚方法无法实现具体的功能 这时需要在基类中声明抽象方法抽象类是指基类的定义中声明不包含任何实现代码的方法 实际上就是一个不具有任何具体功能的方法 这样的方法唯一的作用就是让派生类重写 在基类定义中 只要类体中包含一个抽象方法 该类即为抽象类 在抽象类中也可以声明一般的虚方法 1 声明抽象类与抽象方法声明抽象类与抽象方法均需使用关键字abstract 其格式为 publicabstractclass类名称 publicabstract返回类型方法名称 参数列表 抽象方法不是一般的空方法 抽象方法声明时 没有方法体 只有方法头后跟一个分号 2 重载抽象方法当定义抽象类的派生类时 派生类自然从抽象类继承抽象方法成员 并且必须重写 重载 抽象类的抽象方法 这是抽象方法与虚方法的不同 因为对于基类的虚方法 其派生类可以不必重写 重载 重载抽象类方法必须使用override关键字 重载抽象方法的格式为 pulbicoverride返回类型方法名称 参数列表 其中 方法名称与参数列表必须与抽象类中的抽象方法完全一致 abstractclassAnimal 基类Animal 抽象类 publicabstractvoidSayHello classDog Animal 派生类Dog publicoverridevoidSayHello 重写SayHello Console WriteLine WowWow classCat Animal 派生类Cat publicoverridevoidSayHello 重写SayHello Console WriteLine MewMew classTestClass staticvoidMain

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论