(面向对象程序)6.类的继承与多态.ppt_第1页
(面向对象程序)6.类的继承与多态.ppt_第2页
(面向对象程序)6.类的继承与多态.ppt_第3页
(面向对象程序)6.类的继承与多态.ppt_第4页
(面向对象程序)6.类的继承与多态.ppt_第5页
已阅读5页,还剩41页未读 继续免费阅读

下载本文档

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

文档简介

院级精品课程院级精品课程 面向对象程序设计 安徽机电职业技术学院 信息工 程系 汪 学 文 wxwOOP126.com 2009年9月 ( (使用使用VS 2005VS 2005和和C#)C#) 6 类的继承与多态 6. 类的继承与多态 q面向对象编程(OOP)的三大特性: 封装性 继承性 多态性 q本章主要介绍: 理解继承和软件继承性 理解基类和派生类的概念 理解成员修饰符protected 使用base引用访问基类成员 如何在基类和派生类中使用构造和析构函数 通过一个案例,演示继承机制 2 6.1 继承概述 父类 子类 动物 大象猫 q继承是软件复用的一种形式 。采用这种形式,可吸收现 有类的数据和行为,为其赋 予新功能,从而创建出新类 。软件复用节省了程序开发 时间。它还鼓励人们重用经 过实践检验和调试的高质量 软件,使系统能高效地实现 。 3 6.2 基类和派生类 q日常生活中,一个类的对象也是另一个类的对象。 q如,一个Rectangle(矩形)类“属于”四边形(正方形 、平行四边形和梯形同样是四边形)。也可以说, Rectangle(矩形类)是从Quadrilateral(四边形)类继 承而来的。 Quadrilateral类是基类, Rectangle类 是派生类。 q再如,教师类和学生类可以由大学成员类派生,讲师 、教授又可以由教师类派生,毕业生和在校生又可以 由学生类派生。 4 6.3 保护成员和内部成员 q前面介绍了成员访问修饰符:public和private public成员,可以从程序的任何位置,通过该类(基类或派 生类)的对象引用,来访问它。 private成员,只能在基类的主体中访问它 q再介绍另外两个成员访问修饰符: protected(保护的)成员,只能在基类和它的派生类中访问 。 internal(内部的)成员,可以从同一个程序集(Assembly)中 ,通过类的对象引用,来访问它。 5 6.4 基类和派生类的关系 Point CircleRectangle Cylinder 6 6.4.1:Point类 点(Point)类具有以下属性: 坐标X 坐标Y 且具有以下方法: ToString( ):点的字符串表示形式 示例代码位于“CSharp示例第6课PointCirlceCylinder” 7 Point类演示 示例代码位于“CSharp示例第6课PointCirlceCylinder” 8 6.4.2 Circle类 圆(Ciecle)类具有以下属性: 坐标X 坐标Y 半径Radius 且具有以下方法: Diameter():求直径 CircumFerence():求周长 Area():求圆的面积 ToString():圆的字符串表示形式 9 Circle类:没有使用继承 10 Circle类:没有使用继承 11 Circle类演示 示例代码位于“CSharp示例第6课PointCirlceCylinder” 12 使用类继承 q以上两个类(Point类和Circle类)中的大部分代码非 常类似。程序员最怕的是“重复”劳动,难道需要使 用这种“复制”和“粘贴”的方法吗?这将会造成程 序员最害怕的“代码维护噩梦”。 q我们要用一种更优雅的类构造方法,该方法突出了继 承的优势。下面的例子说明了这一点。 q我们修改Circle类,该类从Point类继承了变量x和y, 及属性X和Y。 注意C#语法中是如何实现类继承的。 13 Circle类:使用继承 public class Circle : Point private double radius; public Circle() public Circle() public double Radius public double Diameter() public double CircumFerence() public double Area() public override string ToString() 14 Circle类:编译出错? q为什么编译会出错?如何改正? 为了让Circle类能直接访问Point类的成员变量x和y, 我们可以在Point类中将这些变量声明为protected。 基类的保护成员可以从基类或其派生类中访问。 下述示例的Point类就是这样改造的类,除了x和y的访 问属性说明为protected以外,其它与Point类相同。 15 修改过的Point类 public class Point protected int x; protected int y; public Point() public Point(int x, int y) / 属性:坐标X public int X / 属性:坐标Y public int Y / 返回点类的字符表示形式 public override string ToString() 16 这时,使用继承的Circle类可以正常运行了 示例代码位于“CSharp示例第6课PointCirlceCylinder” 使用单步调试跟踪程序的运行过程, 看一看,实例化Circle类的对象时, 给Circle类的X和Y属性赋值时,会执 行哪些代码? 17 使用protected成员带来的相关问题 q如同以前使用public一样,在基类中使用protected 成员,会破坏基类的封装性。因为派生类在使用基类 的成员,不知道存在哪些约束,可能会在派生类中给 这些基类成员赋予了无效的值。 q另外一个问题是,派生类的实现可能会依赖于基类。 如果基类的成员发生了变化,可能会导致它所有的派 生类都会发生改变。 v将基类字段声明为private而非protected,能使程序员在更改 基类实现时,不必更改派生类的实现。 v如有可能,要避免在基类中包括受保护数据,相反,应使用非 私有属性和访问私有数据的方法,确保对象维持一致性的状态 。 18 Circle类:继承自Point类 q在派生类中,如何访问基类的私有成员呢? 通过基类中对外公开的属性或方法。 使用base引用进行访问 q通过下页的示例代码和演示大家可以看到这一点。 19 Circle类:继承自Point类 public class Circle : Point private double radius; public double Radius public Circle() this.radius=0; public Circle(int x, int y, double r) : base(x, y) this.radius = r; public double Radius public double Diameter() public double CircumFerence() public double Area() public override string ToString() return “圆心坐标“+base.ToString() +“; 半径“+radius; 20 Circle类演示 示例代码位于“CSharp示例第6课PointCirlceCylinder” 使用单步调试跟踪程序的运行过程, 看一看,实例化Circle类的对象时, 给Circle类的X和Y属性赋值时,会执 行哪些代码? 21 6.4.3 案例演示:三级继承层次结构 q让我们来看一个更现实的继承示例,它牵涉到一个三 级的PointCircleCylinder层次结构 Point Circle3 Cylinder 除继承了Circle类的属性 和方法外,还应具有: Height: 圆柱休高度 Volumn(): 求体积方法 并重载: Area():求圆柱体表面积 22 Cylinder类:定义字段与属性 示例代码位于“CSharp示例第6课PointCirlceCylinder” 23 Cylinder类:构造函数 示例代码位于“CSharp示例第6课PointCirlceCylinder” 24 Cylinder类:定义方法 示例代码位于“CSharp示例第6课PointCirlceCylinder” 25 Cylinder类演示 26 6.4.4 类的多态性演示 示例代码位于“CSharp示例第6课PointCirlceCylinder” 为什么ToString方法能正常显示,而 Area方法不能正确计算? 27 更新后的Circle类和Cylinder类 public class Circle : Point public virtual double Area() return Math.PI * Math.Pow(this.radius,2); public class Cylinder : Circle public override double Area() return 2*base.Area()+base.CircumFerence()*Height; 28 6.5 类的多态性 q上一课的示例Poin-Cirlce-Cylinder,我们简单演示了类的多态 性。 q多态性是一个面向对象的概念,它允许以相似的方式来对待所 有 的派生类,尽管这些派生类是各不相同的。创建派生类的目 的是为了获得更多的特殊功能。 q通过继承,一个类可以用作多种类型:可以用作它自己的类型 、任何基类型,或者在实现接口时用作任何接口类型。这称为 多态性 q在Poin-Cirlce3-Cylinder示例中,计算圆面积的方法与计算圆 柱体的表面积的方法是不相同的,但都可以通过Area( )方法进 行计算,不同对象的Area( )方法是不相同的,但对于调用者来 说,使用很方便(既可以用派生类调用Area( )方法,也可以用基 类调用Area( )方法),因为调用者无需知道计算细节有何不同。 29 6.5.1 基本概念 q所谓多态,就是把派生类对象当成基类对象来使用。 换句话说,就是认为派生类对象是(is a)一种基类对 象。 q把派生类对象当成基类对象来使用,就是“多态”技 术的核心。 q多态性引用只能引用基类的成员。 q多态的实现方式有以下几种: 虚方法 抽象方法 接口 30 6.5.2 虚方法 q如果希望基类中的某个方法能够在派生类中进一步得 到改进,那么可以把这个方法定义为虚方法。 q虚方法就是能在派生类中能够对其实现进一步改进的 方法。 q在基类的定义中,通过virtual关键字来说明该方法 为虚方法。 q在派生类的定义中,如果要重载基类的虚方法,使用 override关键字。 31 6.5.2 虚方法 q在Point-Circle-Cylinder示例中,Point类是基类, 我们在Point类中定义Area和Volume方法为虚方法。 示例代码位于“CSharp示例第6课VirtualMethod” 32 使用虚方法 q如果派生类需要改变某些行为,可以使用override关 键字重载该方法。否则将保持该方法原有的行为。 public class Circle : Point public override double Area() return Math.PI * Math.Pow(this.radius,2); public class Cylinder : Circle public override double Area() return 2*base.Area()+base.CircumFerence()*Height; public override double Volume() return base.Area() * this.Height; 33 属性也可以定义为virtual public class Point public virtual string Name get return “点“; public class Circle : Point public virtual string Name get return “圆“; public class Cylinder : Circle public virtual string Name get return “圆柱体“; 示例代码位于“CSharp示例第6课VirtualMethod” 34 示例代码位于“CSharp示例第6课VirtualMethod” 使用虚方法的类多态性的测试 35 6.5.3 抽象方法 q基类中定义的虚方法,派生类可以重新以新的方式实现(使用 override关键字),也可以不提供实现,这时,调用的是基类 的实现方法。 q有时,在基类定义中,基类不提供实现方法,而要求派生类必 须实现该方法。这时,可以使用抽象方法。 q在定义基类方法时,使用abstract关键字,可以定义抽象方法 。 q抽象方法是一个没有被实现的空方法。 q含有抽象方法的类是抽象类,只能由派生类来继承,而不能用 来实例化对象。相当于定义了一个模板。 q并不要求抽象类必须包含抽象成员。含有抽象成员的类一定是 抽象类。抽象类可以包含非抽象成员。 q从抽象类继承的类的必须实现所有的抽象方法 36 抽象类Shape public abstract class Shape public virtual double Area() return 0.0; public virtual double Volume() return 0.0; public abstract string Name get; 示例代码位于“CSharp示例第6课Abstract” 37 Point类 qPoint类从Shape类继承 qPoint类此时不再是首个基类,需要作部分更改 不需要定义Area方法和Volume方法 重载而不是定义Name属性 q除以上Point、Circle、Cylinder类外,我们还增加 了Rectangle类和Cube类,其继承关系见下页。 38 39 示例代码位于“CSharp示例第7课AbstractSample” 40 6.5.4 接口 q接口与抽象类想像,接口可以定义方法、属性、索引 器和事件。(与抽象类不同,接口不能定义字段) q接口不提供成员的实现,继承该接口的类必须提供接 口成员的实现。 qC#规定类只能实现单继承,但可以实现多个接口。 q一般上,接口发布以后就不能再更改了,这称为接口 的不变性(更改已经发布的接口可能破坏现有代码)。 若需要增加接口的功能,则必须创建新接口。 41 定义IShape接口 q接口的命名,以字母

温馨提示

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

评论

0/150

提交评论