版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、C语言程序设计,第十三章 继 承,1. 继承的概念 面向对象程序设计可以让你声明一个新类作为另一个类的 派生。派生类(也称子类)继承它父类的属性和操作。子类也声 明了新的属性和新的操作。 2. 继承的工作方式 现有一个学生类Student,要增加研究生类GraduateStudent 。由于研究生除了他自己特有的性质外,具有学生的所有性质 ,所以我们用继承的方法来重用学生类。 class Student / ;,class GraduateStudent : public Student / ; 在这里,一个GraduateSyudent类继承了Student类的所有成员。继承的方式是在类定义
2、中类名后跟:public Student。一个研究生是一个学生。当然,GraduateStudent也包含有自己特有的成员。 下例是继承Student的例子,给它添加一些成员: #include #include class Advisor int noOfMeeting; ;,class Student public: Student(char* pName =no name) strncpy(name, pName, sizeof(name); average =semesterHours = 0; void addCourse(int hours, float grade) averag
3、e =(semesterHours*average+grade); /总分 semesterHours +=hours; /总修学时 average /=semesterHours; /平均分 int getHours()return semesterHours; float getAverage()return average; void display() cout name = name “ , hours = semesterHours , average = average endl; ,protected: char name40; int semesterHours; float
4、 average; ; class GraduateStudent :public Student public: getQualifier() return qualifierGrade; protected: Advisor advisor; int qualifierGrade; ; void main() Student ds(Lo lee undergrade); GraduateStudent gs; ds.addCourse (3, 2.5); ds.display(); gs.addCourse(3, 3.0); gs.display(); ,3. 继承与组合 类以另一个类对象
5、作数据成员,称为组合。 例如下面的代码中,定义了一个派生类,该类中包含有类对象成员: class Vehicle / ; class Motor / ; class Car:public Vehicle ,public: Motor motor; ; void vehicleFn(Vehicle 调用vehicleFn(c)是允许的,因为参数要求是车辆,而汽车是车辆的一种。 调用motorFn(c)是不允许的,因为参数要求是马达,而汽,车不是马达,所以参数c不能匹配该函数。 调用motorFn(c.motor)是允许的,因为参数要求是马达,而汽车中包含的马达就是c.motor。 4. 多态性
6、C+允许子类的成员函数重载基类的成员函数。例如,下面的代码中,基类和派生类中都定义了计算学费的成员函数: class Student public: / float calcTuition() /计算学费 / ;,class GraduateStudent:public Student public: / float calcTuition() / ; void main() Student s; GraduateStudent gs; s.calcTuition(); /调用Student:calcTuition() gs.calcTuition(); /调用GraduateStudent:
7、calcTuition() ,有时候,会碰到对象所属的类不能确定的情况。例如将上例作一改动: class Student public: / float calcTuition() /计算学费 / ; class GraduateStudent:public Student public: / float calcTuition() / ;,void fn(Student /计算一下研究生gs的学费 函数调用的实际参数,随应用程序的运行进展而变更,要求函数fn()的行为也要随着变更。这样,函数fn()的运行执行代码就无法在编译时被确定。它一会儿调用Student:calcTuition(),一
8、会儿又调用GraduateStudent:calcTuition()。,C+的继承机制中用一种称为多态性的技术来解决上面的问题。这种在运行时,能依据类型 确认调用哪个函数的能力,称为多态性,或称迟后联编,也有的译为滞后联编。 编译时就能确定哪个重载函数被调用的,称为先期联编。 5. 多态性如何工作 为了指明某个成员函数具有多态性,用关键字virtual来标志其为虚函数。例如: #include class Base public: virtual void fn() cout In Base classn; ; class SubClass :public Base ,public: virt
9、ual void fn() cout In SubClassn; ; void test(Base 由于fn()标志为虚函数,编译看见b.fn()后,将其作为迟后联编来处理,以保证运行时确定调用哪个fn()虚函数。,fn()在基类中声明virtual,该虚函数的性质自动地向下带给其子类,所以SubClass子类中virtual可以省略。 如果虚函数在基类与子类中出现的仅仅是名字的相同,而参数类型不同,或返回类型不同,即使写上了virtual关键字,则也不进行迟后联编。 6. 多继承如何工作 我们可以为一个派生类指定多个基类,这样的继承结构被称为多重继承或多继承。 例如,两用沙发,它是沙发,也是
10、一张床,两用沙发应允许同时继承沙发和床的特征,即SleeperSofa继承Bed和Sofa两个类,如下图所示:,#include class Bed public: Bed() :weight(0) void Sleep() cout Sleeping.n; void SetWeight(int i) weight =i; protected: int weight; ; class Sofa public: Sofa() :weight(0) void WatchTV() cout Watching TV.n; void SetWeight(int i) weight =i; protect
11、ed: int weight; ;,class SleeperSofa :public Bed, public Sofa public: SleeperSofa() void FoldOut() cout Fold out the sofa.n; ; void main() SleeperSofa ss; ss.WatchTV(); ss.FoldOut(); ss.Sleep(); 两用沙发继承两个基类的所有成员,这样ss.Sleep()和ss.WatchTv()的调用是合法的。也就可以把SleeperSofa当作一个Bed或一个Sofa用。另外,SleeperSofa类还有它自己的成员Fo
12、ldOut()。,7. 虚拟继承 床和沙发都是家具的一种,凡家具都有重量,所以通过分解来考察其关系,如下图所示。,#include class Furniture public: Furniture() void SetWeight(int i) weight =i; int GetWeight() return weight; protected: int weight; ; class Bed :public Furniture public: Bed() void Sleep() cout Sleeping.n; ; class Sofa :public Furniture public
13、: Sofa() void WatchTV() cout Watching TV.n; ;,class SleeperSofa :public Bed, public Sofa public: SleeperSofa() :Sofa(), Bed() void FoldOut() cout GetWeight() endl; SleeperSofa不是直接继承Furniture,而是Bed和Sofa各自继承Furniture,所以完整的SleeperSofa对象内存布局如下图所示:,这里一个SleeperSofa包括一个完整的Bed,随后还有一个完整的Sofa,后面还有一个SleeperSof
14、a特有的东西。SleeperSofa中的每一个子对象都有它自己的Furniture部分。因为每个子对象继承Furniture,所以一个SleeperSofa包含两个Furniture对象。,所以程序编译时,不知道SetWeight()属于哪一个Furniture成员。SleeperSofa只需一个Furniture,所以我们希望它只包含一个Furniture拷贝,同时又要共享Bed和Sofa的成员函数与数据成员,C+实现这种继承结构的方法称为虚拟继承。 下面是虚拟继承的代码: #include class Furniture public: Furniture() void SetWeight
15、(int i) weight =i; int GetWeight() return weight; protected: int weight; ; class Bed :virtual public Furniture public: Bed() void Sleep() cout Sleeping.n; ;,class Sofa :virtual public Furniture public: Sofa() void WatchTV() cout Watching TV.n; ; class SleeperSofa :public Bed, public Sofa public: Sle
16、eperSofa() :Sofa(), Bed() void FoldOut() cout Fold out the sofa.n; ; void main() SleeperSofa ss; ss.SetWeight(20); cout ss.GetWeight() endl; 在Bed和Sofa继承Furniture中加上virtual关键字,这相当于说“如果还没有Furniture类,则加入一个Furniture拷贝,否则就,8. 多继承的构造顺序 构造函数按下列顺序被调用: (1) 任何虚拟基类的构造函数按照它们被继承的顺序构造; (2) 任何非虚拟基类的构造函数按照它们被继承的顺序构
17、造; (3) 任何成员对象的构造函数按照它们声明的顺序调用; (4) 类自己的构造函数。 例如: #include class OBJ1 public: OBJ1() cout OBJ1n; ; class OBJ2 public: OBJ2() cout OBJ2n; ; class Base1 public: Base1() cout Base1n; ; class Base2 public: Base2() cout Base2n; ; class Base3 public: Base3() cout Base3n; ; class Base4 public: Base4() cout
18、Base4n; ; class Derived :public Base1, virtual public Base2, public Base3, virtual public Base4 public: Derived() :Base4(), Base3(), Base2(), Base1(), obj2(), obj1() cout Derived ok.n; protected: OBJ1 obj1; OBJ2 obj2; ; void main() Derived aa; cout This is ok.n; ,class Base1 public: Base1() cout Bas
19、e1n; ; class Base2 public: Base2() cout Base2n; ; class Base3 public: Base3() cout Base3n; ; class Base4 public: Base4() cout Base4n; ;,class Derived :public Base1, virtual public Base2, public Base3, virtual public Base4 public: Derived() :Base4(), Base3(), Base2(), Base1(), obj2(), obj1() cout Der
20、ived ok.n; protected: OBJ1 obj1; OBJ2 obj2; ; void main() Derived aa; cout This is ok.n; 9. 继承的访问控制 继承可以公共继承,也可保护继承和私有继承。对于不同的继承方式,其访问控制是不同的。下表列出了其中的区别。,在公共继承的类中,基类的每个成员在子类中保持同样的访问方式。即在基类中为public的成员,子类中可以访问之,并据为public的;基类中为protected的成员,子类也可以访问之,并据为protected的;基类中为private的成员,子类中不能访问之,这就像在应用程序中不能访问类中私有
21、成员一样。 下面的例子中的代码,是对上表的一个解释:,class Base public: int m1; protected: int m2; private: int m3; ; class PrivateClass : private Base /私有继承 public: void test() m1 = 1; /ok:将m1据为private,m2 = 2; /ok:将m2据为private m3 = 3; /不可访问 ; class DerivedFromPri : public PrivateClass public: void test() m1 = 1; /不可访问基类的私有成
22、员 m2 = 2; /不可访问 m3 = 3; /不可访问 ;,class ProtectedClass : protected Base /保护继承 public: void test() m1 = 1; /ok:将m1据为protected m2 = 2; /ok:将m2据为protected m3 = 3; /不可访问 ; class DerivedFromPro : public ProtectedClass public: void test() m1 = 1; / ok:将m1据为protected m2 = 2; / ok:将m2据为protected m3 = 3; /不可访问 ;,class PublicClass : publi
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五年度重型设备运输安全防护及应急响应合同2篇
- 个人出国保证金合同格式(2024年版)版
- 2025年度航空航天飞行控制系统维保与更新合同3篇
- 二零二五年知识产权许可合同管理制度
- 2025年智慧城市建设项目承包合同(升级版)3篇
- 二零二五年度屋顶广告牌LED显示屏租赁服务合同3篇
- 2025年度林业碳汇林权交易市场建设合同4篇
- 2025年度智能仓储设施租赁服务合同范本4篇
- 2025年度场地租赁合同印花税缴纳注意事项及规范4篇
- 二零二五年度房屋买卖合同中合同履行及违约责任2篇
- 大型活动LED屏幕安全应急预案
- 舞蹈课家长会
- 2024年内蒙古包头市中考道德与法治试卷
- 湖南省长沙市2024-2025学年高二上学期期中考试地理试卷(含答案)
- 自来水质量提升技术方案
- 金色简约蛇年年终总结汇报模板
- 农用地土壤环境质量类别划分技术指南(试行)(环办土壤2017第97号)
- 反向开票政策解读课件
- 工程周工作计划
- 房地产销售任务及激励制度
- 六年级语文下册14文言文二则《学弈》课件
评论
0/150
提交评论