继承与组合PPT课件

上传人:沈*** 文档编号:182087010 上传时间:2023-01-20 格式:PPT 页数:81 大小:378KB
收藏 版权申诉 举报 下载
继承与组合PPT课件_第1页
第1页 / 共81页
继承与组合PPT课件_第2页
第2页 / 共81页
继承与组合PPT课件_第3页
第3页 / 共81页
资源描述:

《继承与组合PPT课件》由会员分享,可在线阅读,更多相关《继承与组合PPT课件(81页珍藏版)》请在装配图网上搜索。

1、自行车自行车Bicycle MountainBikesRacingBikesTandemBikesis-a relationships继承的概念继承的概念 现实世界中,组织概念常使用继承来构成现实世界中,组织概念常使用继承来构成一种层次结构,描述的是一种层次结构,描述的是IS-A关系。关系。例如:苹果是一种水果;例如:苹果是一种水果;汽车是一种交通工汽车是一种交通工具等。具等。在在IS-A关系中,每个概念都具有其上一层概关系中,每个概念都具有其上一层概念所有的特性,同时又具有自身的特殊性。念所有的特性,同时又具有自身的特殊性。生物类生物类动物类动物类 植物类植物类 微生物类微生物类脊椎动物类脊

2、椎动物类 其它动物类其它动物类哺乳动物类哺乳动物类 其它脊椎动物类其它脊椎动物类灵长动物类灵长动物类其它动物类其它动物类人人 类类狒狒类狒狒类其它灵长动物类其它灵长动物类继承是允许重用现有类来构造新类的特性。继承是允许重用现有类来构造新类的特性。基类基类方法和属性方法和属性派生类派生类基类方法基类方法+附加方法附加方法 代码的可重用性类库代码的可重用性类库 重定义基类的成员函数重定义基类的成员函数 向派生类添加新成员向派生类添加新成员 不需要了解核心技术的细节不需要了解核心技术的细节1、基类、派生类、基类、派生类 以原有的类为基础产生新类,在这个过程以原有的类为基础产生新类,在这个过程中原有的

3、类称为中原有的类称为基类基类,新类称为,新类称为派生类派生类。汽车类派生出卡车类。在此过程中,我们称汽汽车类派生出卡车类。在此过程中,我们称汽车类为基类,卡车类为汽车类的派生类。车类为基类,卡车类为汽车类的派生类。AB 派生类的声明必须指定基类的名称派生类的声明必须指定基类的名称class Manager:public Employee 任何类都能用作基类任何类都能用作基类 基类分为两种类型基类分为两种类型 直接基类直接基类 间接基类间接基类 处理某企业中雇员的程序处理某企业中雇员的程序EmployeeManager基类派生类派生自 使用使用一个箭头从派生类一个箭头从派生类指向基类指向基类 表

4、示派生类引用基类的表示派生类引用基类的函数和数据,而基类没函数和数据,而基类没有访问派生类有访问派生类的权限的权限class shape private:int m_x,m_y;/位置 char m_color;/颜色public:void setposition(int x,int y);void setcolor(char color);int getx();int gety();char getcolor();classclass TriangleTriangle:publicpublic Shape Shape publicpublic:TriangleTriangle(intint

5、x x,intint y y,charchar colorcolor=RR,floatfloat slenslen=1);=1);floatfloat GetSideLengthGetSideLength()()constconst;voidvoid SetTriangleSetTriangle(intint x x,intint y y,charchar colorcolor,floatfloat slenslen););voidvoid DrawDraw();();privateprivate:floatfloat m_SideLengthm_SideLength;派生新类派生新类:cir

6、cle 圆形圆形 rectangle 矩形矩形 triangle 三角形三角形 基类也称为基类也称为父类父类派生类也称为派生类也称为子类子类 shapecirclerectangletriangle继承多级继承多级继承单一继承单一继承多重继承多重继承层次继承层次继承ABclass A;class B:public A;将类之间的相似性质联系起来将类之间的相似性质联系起来单一继承是从现有基类创建新类的过程单一继承是从现有基类创建新类的过程ABCclass A;class B:public A;class C:public B;直接基类直接基类class A;class B:public A/A是

7、是B的的直接基类直接基类;间接基类间接基类class A;class B:public A;class C:public B/A是是C的的间接基类间接基类;ABC D Eclass A;class B:public A;class C:public A;class D:public C;class E:public C;class A;class B;class C:public A,public B;ABC 派生类的函数派生类的函数 能够访问基类的保护和公有成员能够访问基类的保护和公有成员 派生类的对象派生类的对象 公有派生的类的对象能够访问基类的公有成公有派生的类的对象能够访问基类的公有成

8、员员 私有和保护派生的类的对象不能访问基类的私有和保护派生的类的对象不能访问基类的任何成员任何成员派生类的定义格式派生类的定义格式 class class 派生类名:派生类名:继承方式继承方式 基类名基类名1 1,继承方式继承方式 基类名基类名nn public:public:/派生类公有成员派生类公有成员 private:private:/派生类私有成员派生类私有成员 基类成员基类成员公有继承公有继承私有继承私有继承保护继承保护继承公有公有公有公有私有私有保护保护保护保护保护保护私有私有保护保护私有私有不被继承不被继承不被继承不被继承不被继承不被继承派生派生类不能访问类不能访问基类的基类的私

9、有成员私有成员公有继承不改变基类成员公有继承不改变基类成员的的访问级别访问级别基类的另外两种访问级别使得所有继承的基类的另外两种访问级别使得所有继承的成员与基类成员(私有基类的私有成员或成员与基类成员(私有基类的私有成员或保护基类的保护成员)属于相同的访问级保护基类的保护成员)属于相同的访问级别别 类成员总是能够被它们自己的类的方法访问类成员总是能够被它们自己的类的方法访问 继承类能访问基类的公有或保护成员继承类能访问基类的公有或保护成员 公有成员可以在任何地方被访问公有成员可以在任何地方被访问访问控制说明访问控制说明符符从自身类访从自身类访问问从派生类访从派生类访问问从类外访从类外访问问pu

10、blicpublic可以可以可以可以可以可以protectedprotected可以可以可以可以不可以不可以privateprivate可以可以不可以不可以不可以不可以BaseDerived1Derived2Derived3publicpublicprotectprotectprivateprivate继承的定义格式为:继承的定义格式为:classclass 派生类名派生类名 :继承方式继承方式1 1 基类名基类名1 1,继承方式继承方式2 2 基类名基类名2 2,派生类新定义成员派生类新定义成员 ;类类Person Person、类、类StudentStudent 先调用基类的构造函数,然后

11、调用派生类先调用基类的构造函数,然后调用派生类的构造函数的构造函数class Baseprotected:int a;public:Base()a=0;/默认构造函数默认构造函数 Base(int c)a=c;/单参数构造函数单参数构造函数;class Derived:public Basepublic:Derived():Base()/默认构造函数默认构造函数 Derived(int c):Base(c)/单参数构造函数单参数构造函数;当声明派生类的对象时,当声明派生类的对象时,Derived obj;它将会首先调用基类的构造函数,然后调用它将会首先调用基类的构造函数,然后调用派生类的构造函

12、数派生类的构造函数 基类构造函数是在派生类构造函数之后指基类构造函数是在派生类构造函数之后指定的,使用冒号分隔定的,使用冒号分隔Derived():Base()在派生类的构造函数调用中显式选择基类在派生类的构造函数调用中显式选择基类的构造函数的构造函数Derived obj1(20);调用基类中的相应构造函数调用基类中的相应构造函数Derived(int c):Base(c);派生类的对象的数据结构是由派生类的对象的数据结构是由基类中基类中说明的数据说明的数据成员和成员和派生类中派生类中说明的数据成员共同构成。说明的数据成员共同构成。将派生类的对象中由基类中说明的数据成员和将派生类的对象中由基

13、类中说明的数据成员和操作所构成的封装体称为操作所构成的封装体称为基类子对象基类子对象,它,它由基由基类中的构造函数进行初始化类中的构造函数进行初始化。构造函数不能被继承构造函数不能被继承,对派生类必须,对派生类必须重新定义重新定义构构造函数。造函数。在声明一个派生类对象时,系统在声明一个派生类对象时,系统首先首先要通过派要通过派生类的构造函数生类的构造函数调用基类的构造函数调用基类的构造函数,对基类,对基类成员初始化;成员初始化;然后然后对派生类中新增的成员初始对派生类中新增的成员初始化。化。程序清单程序清单8-2、8-3 调用顺序与构造函数的调用顺序相反调用顺序与构造函数的调用顺序相反 首先

14、调用派生类的析构函数,然后调用基首先调用派生类的析构函数,然后调用基类的析构函数类的析构函数 只有派生类的构造函数通过动态内存管理分只有派生类的构造函数通过动态内存管理分配了内存空间时才需要定义析构函数配了内存空间时才需要定义析构函数 如果派生类的构造函数没有动态内存分配,如果派生类的构造函数没有动态内存分配,那么派生类的析构函数可以是一个空函数那么派生类的析构函数可以是一个空函数 程序清单程序清单8-4 类类Car Car、类、类SportCarSportCar日期和时间日期和时间建立三个类,一个为日期类建立三个类,一个为日期类DateDate,一个为时间类,一个为时间类TimeTime,另

15、一个为上面两个类的派生类,另一个为上面两个类的派生类DateTimeDateTime。例如:例如:#include#include#include#include#include#include typedef char string8080;typedef char string8080;classclass Date Date public:public:Date()Date()Date(int y,int m,int d)SetDate(y,m,d);Date(int y,int m,int d)SetDate(y,m,d);void SetDate(int y,int m,int d)

16、void SetDate(int y,int m,int d)Year=y;Month=m;Day=d;Year=y;Month=m;Day=d;void GetStringDate(string80&Date)void GetStringDate(string80&Date)sprintfsprintf(Date,”%d/%d/%d”,Year,Month,Day);(Date,”%d/%d/%d”,Year,Month,Day);protected:protected:int Year,Month,Day;int Year,Month,Day;将参数表中所提供的将参数表中所提供的各个表达式

17、的值各个表达式的值,按按中所指定的中所指定的格式格式,复制到由复制到由所指定的字所指定的字符数组中符数组中classclass Time Time public:public:Time()Time()Time(int h,int m,int s)SetTime(h,m,s);Time(int h,int m,int s)SetTime(h,m,s);void SetTime(int h,int m,int s)void SetTime(int h,int m,int s)Hours=h;Minutes=m;Seconds=s;Hours=h;Minutes=m;Seconds=s;void G

18、etStringTime(string80&Time)void GetStringTime(string80&Time)sprintfsprintf(Time,”%d:/%d:/%d”,Hours,Minutes,(Time,”%d:/%d:/%d”,Hours,Minutes,Seconds);Seconds);protected:protected:int Hours,Minutes,Seconds;int Hours,Minutes,Seconds;class TimeDate:class TimeDate:public Date,public Timepublic Date,publi

19、c Time public:public:TimeDate():Date(),Time()TimeDate():Date(),Time()TimeDate(int y,int mo,int d,int h,int mi,TimeDate(int y,int mo,int d,int h,int mi,int s):Date(y,mo,d),Time(h,mi,s)int s):Date(y,mo,d),Time(h,mi,s)void GetStringDT(string80&DTstr)void GetStringDT(string80&DTstr)sprintf(DTstr,”%d/%d/

20、%d;%d:/%d:/%d”,sprintf(DTstr,”%d/%d/%d;%d:/%d:/%d”,Year,Month,Day,Hours,Minutes,Seconds);Year,Month,Day,Hours,Minutes,Seconds);派生类构造派生类构造函数函数,本身本身无数据成员无数据成员,函数体为空函数体为空无参构无参构造函数造函数有参构有参构造函数造函数void main()void main()TimeDate date1,date2(1998,8,12,12,45,10);TimeDate date1,date2(1998,8,12,12,45,10);strin

21、g80 DemoStr;string80 DemoStr;date1.SetDate(1998,8,7);/date1.SetDate(1998,8,7);/来自于来自于DateDate基类基类date1.SetTime(10,30,45);/date1.SetTime(10,30,45);/来自于来自于TimeTime基类基类date1.GetStringDT(DemoStr);/date1.GetStringDT(DemoStr);/自身成员函数自身成员函数cout“The date1 date and time is”DemoStrendl;cout“The date1 date and

22、 time is”DemoStrendl;date1.GetStringDate(DemoStr);/date1.GetStringDate(DemoStr);/来自于来自于DateDate基类基类cout“The date1 date is”DemoStrendl;cout“The date1 date is”DemoStrendl;date1.GetStringTime(DemoStr);/date1.GetStringTime(DemoStr);/来自于来自于TimeTime基类基类cout“The date1 time is”DemoStrendl;cout“The date1 tim

23、e is”DemoStrendl;date2.GetStringDT(DemoStr);/date2.GetStringDT(DemoStr);/自身成员函数自身成员函数cout“The date2 date and time is”DemoStrendl;cout“The date2 date and time is”DemoStrendl;The date1 date and time is 1998/8/7The date1 date and time is 1998/8/7;10:30:4510:30:45The date1 date is 1998/8/7The date1 date

24、 is 1998/8/7The date1 time is 10:30:45The date1 time is 10:30:45The date2 date and time is 1987/8/12The date2 date and time is 1987/8/12;12:45:1012:45:10 继承的目的是在一般性的类的基础上生成继承的目的是在一般性的类的基础上生成具有特殊性的类。具有特殊性的类。可能出现重新定义原有函数以实现不同功可能出现重新定义原有函数以实现不同功能的情况,称为能的情况,称为函数的重定义函数的重定义。并且派生类的成员函数可以和基类中的成并且派生类的成员函数可以和

25、基类中的成员函数同名员函数同名 用基类的对象调用函数时,将调用基类的函数用基类的对象调用函数时,将调用基类的函数 使用派生类的对象时,将调用派生类的函数使用派生类的对象时,将调用派生类的函数 派生类的成员函数要调用基类的同名函数,派生类的成员函数要调用基类的同名函数,必须使用作用域解析操作符必须使用作用域解析操作符class Baseprotected:int ss;public:Base();Base(int a)ss=a;int func()return ss;class Derived:public Base public:Derived();Derived(int b)ss=b;int

26、 func()return Base:func();void main()Base b1(10);/基类的对象基类的对象 b1.func();/调用基类的调用基类的func()Derived a1;/派生类的对象派生类的对象 a1.func();/调用派生类的调用派生类的func()#include#include classclass B B private:private:int i;int i;public:public:void set_i(int n)i=n;void set_i(int n)i=n;int get_i()return i;int get_i()return i;cl

27、assclass D:D:publicpublic B B int j;int j;public:public:void set_j(int n)j=n;void set_j(int n)j=n;int nul()return j int nul()return j*get_i();get_i();int main()int main()D ob;D ob;ob.set_i(10);ob.set_i(10);ob.set_j(4);ob.set_j(4);cout();cout();return 0;return 0;obob对象对象set_i(int)set_i(int)get_i()get

28、_i()iprivateprivatepublicpublic从基类从基类B B继承的部分继承的部分jset_j(int)set_j(int)nul()nul()派生类派生类D D自己的部分自己的部分privateprivatepublicpublic如果如果 classclass D:D:publicpublic B B ;继承访问控制方式继承访问控制方式改为:改为:classclass D:D:privateprivate B B ;或;或 classclass D:D:protectprotect B B ;则则D D类中继承的成员、类中继承的成员、obob对象的访问控制是什么情况?对象

29、的访问控制是什么情况?obob对象对象set_i(int)set_i(int)get_i()get_i()iprivateprivatepublicpublic从基类从基类B B继承的部分继承的部分jset_j(int)set_j(int)nul()nul()派生类派生类D D自己的部分自己的部分privateprivatepublicpublicprivateprivateprotectprotectclassclass Base Base private:private:intint b_number;b_number;public:public:Base()Base()Base(int

30、i):Base(int i):b_number(i)b_number(i)intint get_number()return b_number;get_number()return b_number;voidvoid print()cout b_number endl;print()cout b_number endl;classclass Derived:public Base Derived:public Base private:private:intint d_number;d_number;public:public:Derived(int i,int j):Derived(int

31、i,int j):Base(i),d_number(j)Base(i),d_number(j);voidvoid print()print()cout get_number();cout get_number();cout d_number endl;cout d_number endl;int main()int main()Base a(2);Base a(2);Derived b(3,4);Derived b(3,4);cout a is;cout a is;();();cout b is;cout b is;();();cout base part of b is;cout base

32、part of b is;b.Base:print();b.Base:print();return 0;return 0;classclass b b int a;int a;public:public:int get()return a;int get()return a;;classclass d:b d:b int xb;int xb;public:public:void void make()xb=get()+10;make()xb=get()+10;;int int main()main()b ob1;b ob1;d ob2;d ob2;ob2.make();ob2.make();o

33、b2.get();ob2.get();省略为省略为privateprivate class baseclass base public:public:base()coutconstructing base base()coutconstructing base classendl;classendl;base()coutdestructing base base()coutdestructing base classendl;classendl;class subs:public baseclass subs:public base public:public:subs()coutconstr

34、ucting sub subs()coutconstructing sub classendl;classendl;subs()coutdestructing sub subs()coutdestructing sub classendl;classendl;void main()void main()subs s;subs s;注意:注意:在单继承情况下,首先调用基类的构在单继承情况下,首先调用基类的构造函数造函数 ,随后调用派生类的构造函数,随后调用派生类的构造函数,析构函数的调用顺序则正好相反。析构函数的调用顺序则正好相反。组合是一种通过创建一个组合了其他对象的类来获组合是一种通过创建一

35、个组合了其他对象的类来获得新功能的软件重用方法。得新功能的软件重用方法。(描述的是类之间的(描述的是类之间的HAS-A关系)关系)例如:一个汽车的属性中包含了车轮类的对象。例如:一个汽车的属性中包含了车轮类的对象。classclass Wheel Wheel ;classclass Car Car public:public:private:private:int weight;int weight;int speed;int speed;Wheel wheel4;Wheel wheel4;CarSportCarWheel 问题问题:当一个对象作为另一个类对象的数据成员当一个对象作为另一个类对

36、象的数据成员时,构造函数如何被调用?时,构造函数如何被调用?分析:分析:构造函数的调用次序是:构造函数的调用次序是:(1)按类声明中嵌入对象出现的次序,分别调用)按类声明中嵌入对象出现的次序,分别调用个嵌入对象的构造函数个嵌入对象的构造函数 (2)执行本类的构造函数)执行本类的构造函数 程序清单程序清单8-5#include#include classclass base base int n;int n;public:public:base(int a)base(int a)coutconstructing base classendl;coutconstructing base class

37、endl;n=a;n=a;coutn=nendl;coutn=nendl;base()coutdestructing base base()coutdestructing base classendl;classendl;classclass subs:public base subs:public base base bobj;base bobj;int m;int m;public:public:subs(int a,int b,int c):base(a),bobj(c)subs(int a,int b,int c):base(a),bobj(c)coutconstructing sub

38、 cassendl;coutconstructing sub cassendl;m=b;m=b;coutm=mendl;coutm=mendl;subs()coutdestructing sub subs()coutdestructing sub classendl;classendl;voidvoid main()main()subs s(1,2,3);subs s(1,2,3);注意:注意:当派生类中含有对象成员时,构造函数的调用顺序如下:当派生类中含有对象成员时,构造函数的调用顺序如下:1)1)基类的构造函数基类的构造函数2)2)对象成员的构造函数对象成员的构造函数3)3)派生类的构造函

39、数派生类的构造函数析构函数的调用顺序与之相反析构函数的调用顺序与之相反 constrcuting base class constrcuting base class n=1 n=1 constructing base class constructing base class n=3 n=3 constructing sub class constructing sub class m=2 m=2 destructing sub class destructing sub class destructing base class destructing base class destruct

40、ing base class destructing base class 程序程序8-6继承描述的是一种一般性和特殊性的关系,继承描述的是一种一般性和特殊性的关系,使用继承可创建已存在类的特殊版本。使用继承可创建已存在类的特殊版本。组合描述的是一种组成关系,使用组合可组合描述的是一种组成关系,使用组合可用已存在的类组装新的类。用已存在的类组装新的类。继承和组合是两种重要的软件重用方法。继承和组合是两种重要的软件重用方法。class A;class B;class C:public A,public B;ABC可看作是单继承的扩展。可看作是单继承的扩展。程序程序8-7派生类名派生类名 (参数表

41、参数表):):初始化列表初始化列表 派生类构造函数体派生类构造函数体;派生类名派生类名 (参数表参数表):):基类名基类名1 1(实参表(实参表1 1),基类名),基类名2 2(实参表(实参表2 2)派生类构造函数体派生类构造函数体;#include#include class B1 class B1 public:public:B1(int i)b1=i;cout“constructor B1.”Iendl;B1(int i)b1=i;cout“constructor B1.”Iendl;void print()coutb1endl;void print()coutb1endl;privat

42、e:private:int b1;int b1;class B2 class B2 public:public:B2(int i)b2=i;cout“constructor B2.”Iendl;B2(int i)b2=i;cout“constructor B2.”Iendl;void print()coutb2endl;void print()coutb2endl;private:private:int b2;int b2;class class B3 B3 public:public:B3(int i)b3=i;cout“constructor B3.”Iendl;B3(int i)b3=i

43、;cout“constructor B3.”Iendl;int getb3 return b3;int getb3 return b3;private:private:int b3;int b3;class Aclass A:public B2,public B1public B2,public B1 public:public:A(int i,int j,int k,int l):B1(i),B2(j),bb(k)A(int i,int j,int k,int l):B1(i),B2(j),bb(k)a=l;cout“constructor A.”a=l;cout“constructor A

44、.”I I endl;endl;void print()void print()B1:print();B1:print();B2:print();B2:print();couta“,”bb.getb3()endl;couta“,”bb.getb3()endl;private:private:int a;int a;B3 bbB3 bb;void main()void main()A aa(1,2,3,4);A aa(1,2,3,4);();();运行结果:运行结果:1 12 24 4,3 3int main()int main()DeviceNew device(0.7,3,false,10,

45、250,80);DeviceNew device(0.7,3,false,10,250,80);cout“The weight of the device:”();cout“The weight of the device:”();();();();();return 0;return 0;device.Device1:showPower();device.Device1:showPower();void showPower()void showPower()Device1:showPower();Device1:showPower();Device2:showPower();Device2:showPower();BaseBase1Base2Derivedab1ab2c 程序清单程序清单8-8ab1b2cAAB1B2C非虚基类的类层次非虚基类的类层次AB1B2C虚基类的类层次虚基类的类层次

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

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!