资源预览内容
第1页 / 共49页
第2页 / 共49页
第3页 / 共49页
第4页 / 共49页
第5页 / 共49页
第6页 / 共49页
第7页 / 共49页
第8页 / 共49页
第9页 / 共49页
第10页 / 共49页
亲,该文档总共49页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第4章 派生类与继承华东理工大学计算机系 谢晓玲继承的概念o 继承主要是指在己有类的或称为基类的基础上创建新类的 过程,这个新类就是派生类。 o 派生类自动的包含了基类的所有的数据和操作,而且它还 可以增加自身新的成员。 o 继承是面向对象的语言提供的一种重要机制,它在类与类 之间建立了层次关系。交通工具汽车小汽车卡车旅行车工具车轿车面包车继承的概念o 在c+中,有二种继承: o单继承:从一个基类派生的继承。 o多继承:从多个基类派生的继承。继承的概念o 继承机制除了支持软件复用外,还具备以下三个作用: o对事物进行分类。 o支持软件的增量开发。 o对概念进行组合。 o 派生类使我们可以重用已有类的代码和数据结构,并使程 序 易于维护。但类的友元不可被派生类继承。class student ;class GraduateStudent: :public student ;void fn(student fn(gs);/student gs对象GraduateStudent 新定义的自身成员从基类Student 继承下来的基类成员派生类的定义o单继承的格式:class 派生类: 继承方式 基类 派生类新定义成员; o多继承的格式:class 派生类: 继承方式1 基类1, 继承方式2 基类2,. 派生类新定义成员;需要注意的是,基类的构造函数和析构函数不能 被派生类继承,派生类若要初始化基类的数据成员必 须在构造函数中初始化。派生类的继承方式o 继承方式有3种: opublic(公有继承) 基类的公用成员和保护成员被派生类继承,并保持 原有的状态。 2. private(私有继承) 基类的公用成员和保护成员被派生类继承,作为派 生类的私有成员。以后不能被这个派生类的子类所继 承。 3. protected(保护继承) 基类的公用成员和保护成员被派生类继承,作为派 生类的保护成员。并且只能被派生类的成员函数或友 元访问。不同的继承方式,导致原有基类成员在派生类中的 访问属性也有所不同。基类成 员的权 限继承方式publicprotectedprivatepublic在派生类中为public在派生类中为 protected在派生类中为private派生类的成员函数和类的 作用域之外,都可以直接 访问派生类的成员函数可以直 接访问派生类的成员函数可以直 接访问protec ted在派生类中为 protected在派生类中为 protected在派生类中为private派生类的成员函数可以直 接访问派生类的成员函数可以直 接访问派生类的成员函数可以直 接访问privat e在派生类中被隐藏,无法 访问不可访问在派生类中被隐藏,无法 访问不可访问在派生类中被隐藏,无法 访问不可访问任何方式都不能直接访问 ,但可以通过基类的 public、protected成 员函数间接访问任何方式都不能直接访问 ,但可以通过基类的 public、protected成 员函数间接访问访问任何方式都不能直接访问 ,但可以通过基类的 public、protected成 员函数间接访问访问o 若派生类的成员函数与基类的成员函数同名,则派生类的成 员函数覆盖继承下来的同名的基类的成员函数。 o “基类:成员函数”,则编译器认为是基类的成员函数。 o “不可访问”的成员是限制还要严格的成员,即使是类自身的 成员函数也不能访问。 o “不可访问”的成员总是由基类继承下来的,它要么是基类的 不可访问成员,要么是基类的私有成员。 o 公有派生类是基类的一种,其对象可用于基类对象适用的任 何地方。建议使用公有派生。公有派生类=基类成员 + 自身成员派生类的继承方式#include using namespace std; class Base private: int a; void fun1() cout #include using namespace std; class Date /日期类private: int year,mon,day; /年、月、日成员变量public: Date(int y=2009,int m=6,int d=10) /构造函数 year=y;mon=m;day=d; void Print() /输出数据,格式为:年-月-日 cout #include class Employee /职员类protected: char ename20;/职员名字 char jobname20;/工作名public: Employee(char *strName,char *strJob) /构造函数 strcpy(ename, strName); strcpy(jobname, strJob); cout using namespace std; class B1 /基类B1public: int m;/成员变量m B1() m=0; /构造函数 ; class B2 /基类B2public: int m;/成员变量m B2() m=100; /构造函数 ;基类成员访问和赋值兼容性class D:public B1,public B2 /派生类 Dpublic: void Test()/cout using namespace std; class B1 /基类B1int m;public: void print()cout using namespace std; class Circle /圆类protected: float radius; /半径public: Circle (float r) /构造函数radius=r; float Area() /求圆面积return 3.14f * radius * radius; float Area(float r) /求圆面积radius=r; return 3.14f * radius * radius; ;同名成员覆盖class Cylinder: public Circle /圆柱体派生类private: float height; /高度public: Cylinder (float r,float h) :Circle(r) /构造函数 height=h; float Area() /同名成员覆盖了基类的Area()和 Area(float) float botarea=0,sidearea=0; botarea=Circle:Area()*2; /底面积*2 sidearea=2*3.14f*radius*height; /侧面积 return botarea+sidearea; float Volume() /圆柱体积 return Circle:Area()*height; /基类求面积乘高度 ;同名成员覆盖int main() Cylinder cr1(10,5);/定义圆柱体对象 cout class A /基类Apublic:A() a=0; A(int I) a=I; void print() coutprint();fun(bb); /A 派生类类的对对象初始化基类类引用 a:9 b:5bb,da:5aaa:9aaa:1 b:2pb- pa-虚基类问题的提出 o 在多继承关系中,如果某个派生类D的多个直接基类(如类 Bl 和B2 )是从另一个公共基类B0派生而来(如图所示),则 在派生类对象中会存在基类B0的多个副本的二义性问题。虚基类设置虚基类以解决二义性 o 将共同基类B0设置为虚基类,让基类Bl和B2从基类B0虚拟 继承,这时从不同的路径继承过来的同名数据成员在派生类中 就只有一个副本。 o 使用虚基类,可以使公共基类的成员在其间接派生类中只 保留一份。即:使公共基类在派生类对象中只产生一个基类子 对象。 o 定义虚基类的格式如下: class 派生类名:virtual 继承方式 基类名称 ;class B0 public: int nv0; ; class B1: virtual public B0 public: int nv1; ; class B2: virtual public B0 public: int nv2; ;class D0: public B1,public B2 public: int nv3; ; void main()D0 d; 虚基类关于虚基类的初始化,有如下规则: 1. 规定将在建立对象时所指定的类称为最派生类。 2. 只有用于建立对象的那个最派生类的构造函数才会调用 虚基类的构造函数,而该派生类的其他基类在成员初始化列表 中对虚基类构造函数的调用都会被忽略,从而保证了在派生类 对象中虚基类成员只会被初始化一次。 3. 如果虚基类定义了有带形参的构造函数,而没有定义缺 省构造函数,则整个继承结构中,所有从虚基类直接或者间接 派生类,必须在该类构造函数的成员初始化列表列出对虚基类 构造函数的调用。如未被列出,则表示使用该虚基类的缺省构 造函数来初始化派生类对象中的虚基类子对象。建议虚基类提 供缺省构造函数。虚基类4. 若某派生类构造函数的成员初始化列表中同时列出对虚 基类构造函数和非虚基类构造函数的调用,则会优先执行虚基 类的构造函数。 5. 对于多个虚基类或多个非虚基类,构造函数的执行顺序 是先左后右,自上而下。 6. 构造函数按下列顺序被调用: o任何虚基类的构造函数按照它们被继承的顺序构 造; o任何非虚基类的构造函数按照它们被继承的顺序 构造; o任何成员对象的构造函数按照它们声明的顺序构 造; o派生类的构造函数;#include using namespace std; class Base /虚基类Base public: Base(int a) /有参构造函数val=a; void Print() cout class A1public:A1()cout“A1 class!“endl; ; class A2 int a,b;public:A2(int aa=0,int bb=0) a=aa;b=bb;cout“A2 class!“endl;void show()cout“A2:a=“a“,b=“bendl; ; class B1:public A1,virtual public A2public:B1(int a,int b):A2(a,b) cout“B1 class!“endl; ; class B2:public A1,virtual public A2public:B2(int a,int b):A2(a,b) cout“B2 class!“endl; ;class C:public B1,virtual public B2public:C(int a,int b):B1(a,b),B2(a,b) cout“C class!“endl; ; void main() C obj(7,9); obj.show(); A1 A2V V B2 B1C
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号