资源预览内容
第1页 / 共41页
第2页 / 共41页
第3页 / 共41页
第4页 / 共41页
第5页 / 共41页
第6页 / 共41页
第7页 / 共41页
第8页 / 共41页
第9页 / 共41页
第10页 / 共41页
亲,该文档总共41页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
类的继承 继承与派生问题举例类的继承 继承与派生问题举例类的继承继承与派生的目的继承的目的:实现代码重用。派生的目的:当新的问题出现,原有程序无法解决(或不能完全解决)时,需要对原有程序进行改造。类的继承基类和派生类的概念基类和派生类的概念在继承关系中,新定义的类称为被继承类 的派生类或子类,而被继承的类称为新定 义类的基类或父类。派生类继承了基类的 所有成员。一个派生类也可以作为另一个派生类的基 类。类的继承派生类的定义派生类的定义class : . . . / 派生类新增加的成员声明列表 ; 说明:派生方式决定了基类的成员在派生类中的访问权限。派生方 式共有三种:public、private和protected(缺省值为private )。虽然派生类继承了基类的所有成员,但为了不破坏基类的封 装性,无论采用哪种派生方式,基类的私有成员在派生类中 都是不可见的,即不允许在派生类的成员函数中访问基类的 私有成员。类的继承class CPerson private:char m_name12;char m_ID18;int m_age; public:/ ; class CStudent : public CPerson private:char m_student22;/学校char m_number18;/学号/ ;类的继承类的访问权限控制回顾lpublic属性:表示数据成员和成员函数是类 的公有成员,它们允许被本类的成员函数访 问或调用,也允许通过对象访问或调用,是 类的外部接口。lprotected属性:表示数据成员和成员函数 是类的保护成员,它们允许被本类的成员函 数和派生类的成员函数访问或调用。lprivate属性:表示数据成员和成员函数是类 的私有成员,它们只允许被本类的成员函数 访问或调用。类的继承三种派生方式的区别三种派生方式的区别采用public派生,基类成员的访问权限在派生类中保持不 变,即基类所有的公有或保护成员在派生类中仍为公有 或保护成员。public派生最常用。可以在派生类的成员函数中访问基类的非私有成员;可通过派生类的对象直接访问基类的公有成员。采用protected保护派生,基类所有的公有和保护成员在 派生类中都成为保护成员,只允许在派生类的成员函数 和该派生类的派生类的成员函数中访问基类的非私有成 员。 采用private私有派生,基类所有的公有和保护成员在派 生类中都成为私有成员,只允许在派生类的成员函数中 访问基类的非私有成员。private派生很少使用。类的继承例 定义类Point,然后定义类Point的派生类Circle 。#include class Point/ 定义基类,表示点 private:int x;int y; public:void setPoint(int a, int b) x=a; y=b; ; / 设置坐标int getX() return x; ;/ 取得X坐标int getY() return y; ;/ 取得Y坐标 ;类的继承class Circle : public Point / 定义派生类,表示圆 private:int radius; public:void setRadius(int r) radius=r; ; / 设置半径int getRadius() return radius; ; / 取得半径int getUpperLeftX() return getX()radius; ; / 取得外接正方形左上角的X坐标int getUpperLeftY() return getY() + radius; ; / 取得外接正方形左上角的Y坐标 ;类的继承main() Circle c;c.setPoint(200, 250);c.setRadius(100);cout class A public: void Show( ) cout ) : A( ) . . . / 类B构造函数的实现代码 派生类构造函数既初始化派生类的数据成员,又 通过基类构造函数初始化其基类的数据成员。参数表中参数的个数和类型要与基类某个构造函 数的形参声明一致。形参声明中的部 分参数,传递给 基类构造函数 派生类构造函数形 参的名称和类型 类的继承注 意当基类有多个构造函数时,编译器根据派生 类构造函数为基类构造函数提供的参数表 来确定调用基类的哪一个构造函数。类的继承例 首先定义类Point,然后定义类Point的派生类 Circle,再定义类Circle的派生类Cylinder。Point Circle Cylinder(x, y)(x, y)r(x, y)hr类的继承#include class Point/ 定义基类Point protected:int x, y; public:Point(int a=0, int b=0) / 含有缺省参数值的构造函数也是默认的构造函数 x=a; y=b; cout #include class CPerson private:char m_name12; char m_ID18; int m_age; public:CPerson(char name,char ID,int age) strcpy(m_name,name);strcpy(m_ID,ID);m_age=age;cout :virtual 采用虚基类方式定义派生类的方法是在基类的前面加 上关键字virtual,而定义基类时与一般基类完全一样。 类的继承例 采用virtual虚基类方式定义派生类。 class Aclass A public:public:int a;int a; ;class B class B : : virtualvirtual public Apublic A public:public:int b; int b; ;class C : class C : virtualvirtual public Apublic A public:public:int c; int c; ;class D : public B, public C class D : public B, public C / / 类类D D派生于类派生于类B B和类和类C C public:public:int d; int d; ;main()main() D d1; D d1;d1.a=100;d1.a=100; 类的继承虚基类的初始化虚基类的初始化虚基类的初始化与一般多继承的初始化在语法上相同 ,但构造函数的调用顺序有所不同,规则如下:v先调用虚基类的构造函数,再调用非虚基类的构造 函数。v若同一层次包含多个虚基类,其调用顺序为定义时 的顺序。v若虚基类由非虚基类派生而来,则仍按先调用基类 构造函数,再调用派生类构造函数的顺序。类的继承引入虚基类后构造函数的调用顺序举例引入虚基类后构造函数的调用顺序举例 #include class Base1 public: Base1() cout“class Base1“; coutendl; ; class Base2 public: Base2() cout“class Base2“; coutendl; ; class Level1:public Base2,virtual public Base1 public: Level1() cout“class Level1“; coutendl; ;class Level2:public Base2,virtual public Base1 public: Level2() cout“class Level2“; coutendl; ; class TopLevel:public Level1,virtual public Level2 public: TopLevel() cout“class TopLevel“; coutendl; ; void main() TopLevel obj; 运行结果: class Base1 class Base2 class Level2 class Base2 class Level1 class TopLevel类的继承使用虚基类派生方式的好处使用虚基类派生方式的好处节约内存空间;避免在多重派生类中类成员的 不明确性。 类的继承类的继承小结类的继承小结J继承是基类创建一个派生类的过程;J继承是实现代码重用的重要手段;J派生类的生成经历了三个过程:吸收基类 的成员、改造基类的成员和添加派生类新 成员;J三种继承方式:公有、私有和保护继承;J基类构造函数的调用:显示和隐式;J继承分单继承和多继承。
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号