C++课件第十一章继承和派生类.ppt_第1页
C++课件第十一章继承和派生类.ppt_第2页
C++课件第十一章继承和派生类.ppt_第3页
C++课件第十一章继承和派生类.ppt_第4页
C++课件第十一章继承和派生类.ppt_第5页
已阅读5页,还剩35页未读 继续免费阅读

下载本文档

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

文档简介

第十一章 继承和派生类,类是一种抽象数据类型,是对具有共同属性和行为的对象(事物)的抽象描述。,顶层的抽象事物具有处于底层的抽象事物的共同特 征,而处于底层的抽象事物除了包含顶层抽象事物的 特征外,还具有自身的我特征。,一个类继承另一个类时,这个类被称为继承类、派生类或子类,另一个类被称为被继承类、基类或父类。 继承类包含了被继承类中的所有成员,且有自己的成员。,继承:从一个或多个先前定义过的类(称为基类)中接受全部或一部分数据(属性)或函数(行为或操作),并且补充定义新的数据或函数,因而形成一个新的低层的类(称为派生类)。而该派生类还可用作更低层派生类的基类。,class demo protected: int j; public: demo()j=0 void add(int i) j+=i; void display( ) coutjendl; ;,1 派生类定义的格式,class child:public demo public: void sub(int i)j-=i; ;,void main(void) child object,object1; object.display(); object.add(10); object.display(); object.sub(5); object.display(); object1.display;,0,10,5,0,定义派生类的基本格式: class 派生类名:继承权限 基类名 继承权限:public,protected,private 影响的是被继承的原基类成员的访问权限 class定义的默认为private,struct定义的默认为public,继承权限为public时,称该派生为公有派生。 基类中的所有public成员在派生类中仍是public成员,所有protected成员在派生类中仍是protected成员。 继承权限为private时,称该派生为私有派生。 基类中的public成员和protected成员在派生类中均变成private成员。 继承权限为protected时,称该派生为保护派生。 基类中的public成员和protected成员在派生类中均变成protected成员。,无论哪一种继承权限,其基类的private成员均不能为派生类所继承。但可通过被同时继承下来的原基类的某些函数间接访问它们。,private:aa1 protected:aa2 public:aa3,A,Class B:public A private:bb1 protected:bb2 public:bb3 ,private:bb1 protected: aa2 bb2 public: aa3 bb3,B,公有派生,private:aa1 protected:aa2 public:aa3,A,Class B:protected A private:bb1 protected:bb2 public:bb3 ,private:bb1 protected: aa2 bb2 aa3 public: bb3,B,保护派生,private:aa1 protected:aa2 public:aa3,A,Class B: A private:bb1 protected:bb2 public:bb3 ,private:bb1 aa2 aa3 protected: bb2 public: bb3,B,私有派生,2 派生类的使用,#include class employee private: char *name; short age; float salary; public: employee( ) name=0; age=0; salary=0.0; employee(char *name1, short age1, float salary1) name=new charstrlen(name1)+1; strcpy(name,name1); age=age1; salary=salary1; ,void print( ) const /const成员函数:不能改变类中成 员数据的值,也不能调用类中非 const成员函数 cout“name:”name; cout“age:”age; cout“salary:”salaryendl; employee( ) delete name; ;,Manager: 除具有employee的属性外,有新的属性。为避免重复定义,可从employee中派生出manager(派生类)。,class manager: public employee private: int level; public: manager( ) level=0; manager(char *name1, short age1, float salary1, int level1): employee(name1, age1, salary1) level=level1; void print_level( ) cout“level:”levelendl; ;,派生类构造函数: 使用初始化符表初始化基类中的成员。,缺省构造函数 若基类无缺省构造函数,将出错,void main() manager m(“xyz“,24,1000,2); m.print_level(); m.print(); m.employee:print(); ,void main() manager n; n.print_level() ; n.print(); ,若a是Y从X类中继承来的公用成员,设y是Y的一个对象 ,则可访问y.a或y.X:a,protected 访问指明符: 外部函数不能访问; 派生类成员函数可直接访问。 class employee private: short age; float salary; protected: char *name; / ;,派生类成员函数: void manager:print_name( ) const coutnameendl; ,外部函数: void f( ) manager m; endl; /错 ,继续派生: class director: public manager / ,employee,多层继承,class x protected: int i, j; public: x(int i, int j) x:i=i, x:j=j; void print() cout “i=“ i “ j=“ j endl; ;,class y : public x int k; public: y(int i, int j) : x(i, j) k = i * j; /初始化列表 void print() cout “i=“ i “ j=“ j“ k=“kendl; ;,支配规则(就近原则),class z : public y public: z(int i, int j) : y(i, j) /初始化列表 void print1() cout “i=“ i “ j=“ jendl; void print() y:print(); ;,void main() y y1(23, 45); y1.print(); y1.x:print(); z z1(10, 20); z1.print(); z1.print1(); z1.y:print(); z1.x:print(); ,i=23 j=45 k=1035,i=23 j=45,i=10 j=20 k=200,i=10 j=20,i=10 j=20 k=200,i=10 j=20,对属于基类的成员进行初始化是通过初始表中的初始化项来初始化的。若初始化表中没有调用基类的初始化项,则自动调用基类的无参构造函数进行初始化。 如果派生类的自有成员和继承成员同名,则自有成员优先,即通过这个共同的成员名所访问的是自有成员,而不是继承成员,这种情况下,可以在成员名前加类区分符将同名成员区分开。(支配规则) 作用域运算符不能连续使用,即下列形式是不允许的:CName1:Cname2:Cnamen 作用域运算符的左操作数可以是当前对象的直接基类,也可以是当前对象的间接基类(祖先类)。,3 多重继承与冲突,由多个基类派生出一个子类称之为多重继承 在多重派生中,如果不同的基类具有名字相同的共有成员或保护成员,此时若在派生类中不正确使用它们,就会产生二义性,这种情况称之为冲突,【例】冲突的程序示例。 class A protected: int x; public: A(int a)x=a; void Show(void) cout“x=“xn; ; class B protected: int x; public: B(int a)x=a; void Show(void) cout“x=“xn; ;,class C:public A, public B /多重继承 int y; public: C(int a , int b):A(a) , B(b) /多重继承的初始化 / void Setx(int a) /x=a; / 冲突 A:x=a; /正确(冲突的解决办法:在成员名 前加上基类名) void Sety(int b) y=b; int Gety(void) return y; ;,void main(void) C c1(10,100); /c1.Show(); / 冲突 c1.B:Show(); /正确 ,class B1 protected: int x; public: void Show() cout“x=“xn; ; class B2 protected: int x; public: void Show() cout“x=“xn; ;,class D1:public B1 ; class D2:public B2 ; class C:public D2,public D1 public: /void Setx1(int a)D1:B1:x=a; / 错误,域运算 符不能连续使用 void Setx1(int a)D1:x=a; /正确,或为B1:x=a; void Setx2(int a)D2:x=a; /正确,或为B2:x=a; ;,void main(void) C c; c.Setx1(2); /c.D1:B1:Show(); / 错误,域运算符不能连续使用 c.SetX2(3); c.D2:Show(); /正确,或为c.B2:Show(); ,4 构造、析构函数的调用顺序,构造函数的调用顺序只与派生类继承基类的顺序有关,而与初始化成员列表中构造函数顺序无关。 一个类的构造函数只能对它的直接基类的构造函数传递实参。,派生类所不能继承的:,5 访问类型的调整,有时为了某种目的,需要将从派生类继承的内容的访问类型进行调整,这时可以通过访问声明进行。访问声明的一般格式为: :; 其中,必须基类的public和protected类型的成员名。 在访问声明时仅仅说明基类成员名,即对成员数据不可以为它说明数据类型,对成员函数不可以说明参数和返回值类型。,【例】 用访问声明调整访问类型 class Cbase int x; protected: int y; public: int Fun(int a,int b) return a; ; class CDerived:Cbase protected : /int CBase:y; /错误,数据成员的访问声明中不能有类型 CBase:y; /正确 public: /int CBase:Fun(int,int); /错误,成员函数的访问声明不 能有参数和返回值类型 CBase:Fun; /正确 ;,访问声明不允许在派生类中改变基类成员的访问类型,即基类中的protected成员在派生类中只能调整为protected类型,基类中的public成员在派生类中只能调整为public类型。 对基类中重载函数进行访问声明,将会调整基类中所有具有该名的函数的访问类型。如果在派生类中有与基类中同名的函数,也允许在派生类中对该函数进行访问声明。,6 赋值兼容规则,赋值兼容规则是指,在具有继承关系的类之间: 1. 公有派生类对象可直接赋值给基类的对象 2. 基类对象不可以赋给派生类对象 3. 公有派生类对象的地址可赋给基类指针变量 4. 公有派生类对象可以初始化基类引用 5. 在将公有派生类的对象赋给基类对象之后,基类对象只能访问派生类中从基类继承的公有成员,不能访问派生类中增加的公有成员。,【例】 赋值兼容规则 class Cbase protected: int x; public: CBase(int a)x=a; void Show1() cout“x=“xn; ; class CDerived:public Cbase protected: int y; public: CDerived(int a,int b):CBase(b) y=a; void Show1() cout“y=“yn; void Show2() cout“y=“yn; ;,void main() Cderived c(2,3); Cbase b1(4),*b2; Cbase /错误,理由同上 ,7 虚基类,基类A被一个派生类D多次继承,类D产生两个类A的副本。,(virtual),虚基类的类层次,虚基类的基本思想是:当将一个基类声明为虚基类时,不管它在派生类中被继承多少次,该基类中的成员在该派生类中始终都只有一个拷贝(即所有派生类均共享基类成员)。 虚基类通过关键字Virtual实现。,class A private: int x; public: void setx(int a)x=a; void getx()coutxendl; ; class B:public A ; class C:public A ; class D:public B,public C ; void main() D m; m.B:setx(3); m.B:getx(); m.C:setx(4); m.C:getx(); /m.A:setx(5); /会产生冲突 /m.A:getx(); /会产生冲突 ,非虚基类继承,3,4,class A private: int x; public: void setx(int a)x=a; void getx()coutxendl; ; class B:virtual public A ; /定义虚基类 class C:virtual public A ; /定义虚基类 class D:public B,public C ; void main() D m; m.B:

温馨提示

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

评论

0/150

提交评论