《继承与派生》PPT课件.ppt
《《继承与派生》PPT课件.ppt》由会员分享,可在线阅读,更多相关《《继承与派生》PPT课件.ppt(124页珍藏版)》请在三一办公上搜索。
1、第11章 继承与派生第12章 多态性与虚函数第13章 输入输出流第14章 C+工具,第4篇面向对象的程序设计,第11章 继承与派生,11.1 继承与派生的概念11.2 派生类的声明方式11.3 派生类的构成11.4 派生类成员的访问属性11.5 派生类的构造函数和析构函数11.6 多重继承11.7 基类与派生类的转换11.8 继承与组合11.9 继承在软件开发中的重要意义,面向对象程序设计有4个主要特点:抽象封装继承多态性面向对象技术强调软件的可重用性(software reusability)。C+语言提供了类的继承机制,解决了软件重用问题。,在C+中可重用性是通过继承(inheritanc
2、e)这一机制来实现的。继承是C+的一个重要组成部分。在C+中,所谓“继承”就是在一个已存在的类的基础上建立一个新的类。见图11.1示意。,11.1 继承与派生的概念,已存在的类(例如“马”)称为“基类(base class)”或“父类(father class)”。新建立的类(例如“公马”)称为“派生类(derived class)”或“子类(son class)”。见图11.2示意。,图11.1 图11.2,一个派生类只从一个基类派生,这称为单继承(single inheritance),这种继承关系所形成的层次是一个树形结构,见下图。箭头表示继承的方向,从派生类指向基类。,一个派生类不仅可
3、以从一个基类派生,也可以从多个基类派生。一个派生类有两个或多个基类的称为多重继承(multiple inheritance)。,关于基类和派生类的关系:派生类是基类的具体化,而基类则是派生类的抽象。,声明派生类的一般形式为:class 派生类名:继承方式 基类名派生类新增加的成员;继承方式包括:public(公用的),private(私有的)和protected(受保护的),如果不写此项,则默认为private(私有的)。,11.2 派生类的声明方式,派生类分为两大部分:一部分是从基类继承来的成员另一部分是在声明派生类时增加的部分每一部分均分别包括数据成员和成员函数。,11.3 派生类的构成,
4、构造一个派生类包括以下4部分工作:,派生类对象结构,对于下面的继承关系:class Father int a,b;public:/成员函数;class Son:public Father int c;public:/成员函数;,基类对象子类对象子类对象空间总是不小于基类对象,c,a,b,a,b,基类部分,子类添加部分,11.4 派生类成员的访问属性,继承可以公有继承,保护继承和私有继承。公有继承是普通继承,基类可以为大多数应用服务。也可以重复继承。保护继承是“单传”继承,只继承给自己的后代,应用是以子孙的公有成员函数来对外展开服务的。私有继承是“绝版”继承,该基类只继承直接的子类,而不考虑让子
5、类再继承下去。,public继承:基类的public成员,在派生类中成为public成员基类的protected成员,在派生类中成为protected 成员基类的private成员,在派生类中成为不可直接使用的成员,11.4.1 公有继承,表11.1公用基类在派生类中的访问属性,例:下面定义了两个具有单继承关系的类A和B,其中,A为基类,B为派生类:,class Aint x,y;public:void f();void g();class B:public Aint z;public:void h();,在C+中对派生类有以下几点规定:派生类除了拥有基类的所有成员(基类的构造函数和赋值操作符
6、重载函数除外)外,也可以具有新的成员。,class Aint x,y;public:void f();void g();class B:public Aint z;public:void h();,void main()B b;b.f();/A类中的 fb.g();/A类中的gb.h();/B类中的h,派生类的定义用于描述派生类与基类的差别。派生类中可以给出新的成员,也可以对基类的成员进行重定义。如果在派生类中对基类的某个成员进行重定义,则在派生类中对该成员的访问是针对派生类中重定义的成员。,class B:public Aint z;public:void f();void h()f();/
7、B类中的f g();/A类中的g;void main()B b;b.f();/B类中的 fb.g();/A类中的gb.h();/B类中的h,派生类成员名的作用域嵌套在基类的作用域中,对于基类的一个成员,如果派生类中没有定义与其同名的成员,则该成员名在派生类的作用域内可见,否则,该成员名在派生类的作用域内不直接可见,如果要使用,必须用基类名受限。例:,class B:public Aint z;public:void f();void h()f();/B类中的f A:f()/A类中的f;void main()B b;b.f();/B 类中的 fb.A:f();/A类中的f,即使派生类中定义了与基
8、类同名但参数不同的成员函数,基类的同名函数在派生类中的作用域中也是不直接可见的。例:,class B:public Aint z;public:void f(int);void h()f(1);/Ok f();/A:f()/Ok;void main()B b;b.f(1);/Okb.f();/b.A:f();/Ok,定义派生类时一定要见到基类的定义,否则编译程序无法确定派生类对象需占多大内存空间以及派生类中对基类成员的访问是否合法。例:,class A;class B:public Aint z;public:void h()g();/Error没有g的原型;B b;/Error无法确定 b
9、所需空间,如果在派生类中没有显式说明,基类的友元不是派生类的友元;如果基类是另一个类的友元,而该类没有显式说明,则派生类也不是该类的友元。派生类不能直接访问基类的私有成员,必须要通过基类的非私有成员函数来访问基类的私有成员。例:,class A int x,y;public:void f();void g()x;class B:public Aint z;public:void h()x/Error,x为基类的私有成员g();/Ok,通过函数g访问基类的私有成员x;,在派生类中对基类成员的访问一个类有两种用户:实例用户和派生类。例:一个类存在两个对外接口给实例用户使用:由类的public成员构
10、成提供给派生类使用:由类的public和protected成员构成,class A;class B:public A/派生类;void f()/实例用户 A a;,class A protected:int x,y;public:void f();class B:public A/派生类 void h()x/Ok y/Ok f();/Ok;void f()/实例用户 A a;a.x/Errora.y/Errora.f();/Ok;,类的聚集:一个类只有一个接口,即类的实例用户接口。例:以继承和聚集实现的代码重用。,class A public:void f();void g();class B
11、:public A public:void h();,class B A a;public:void f()a.f();void g()a.g();void h();,继承实现子类型,派生类可以看成基类的子类型。子类型的作用:发给基类对象的消息也能发给派生类对象,以及基类的对象标识可以标识派生类对象。,class A public:void f();class B:public A public:void g();,以下操作合法:A a,*p;B b,*q;b.f();a=b;p=/Error,用b去改变a的状态,属于b但不属于a的成员将被忽略,A类指针p指向B类对象b,例11.1 访问公有基
12、类的成员。Class Student/声明基类public:/基类公用成员 void get_value()cinnumnamesex;void display()cout num:numendl;cout name:nameendl;cout sex:sexendl;private:/基类私有成员 int num;char name8;char sex;class Student1:public Student/以public方式声明派生类Student1,public:void display_1()cout num:numendl;cout name:nameendl;/引用基类的私有成
13、员,错误 cout sex:sexendl;cout age:ageendl;/引用派生类的私有成员,正确 cout address:addrendl;/引用派生类私有成员,正确private:int age;char addr12;,结论:由于基类的私有成员对派生类来说是不可访问的,因此在派生类中的display_1函数中直接引用基类的私有数据成员num,name和sex是不允许的。只能通过基类的公用成员函数来引用基类的私有数据成员。,可以将派生类Student1的声明改为:class Student1:public Student/以public方式声明派生类Student1public:
14、void display_1()coutageaddr;private:int age;string addr;,可以这样写main函数:int main()Student1 stud;stud.get_value();stud.get_value_1();stud.display();stud.display_1();return 0;,void display_1()display();cout“age:“ageendl;cout“address:“addrendl;,void get_value_1()get_value();Cinageaddr;,private继承:基类的public
15、成员,在派生类中成为private 成员基类的protected成员,在派生类中成为private成员基类的private成员,在派生类中成为不可直接使用的成员,11.4.2 私有继承,表11.1私有基类在派生类中的访问属性,图11.7表示了各成员在派生类中的访问属性。,例11.2 将例11.1中的公用继承方式改为用私有继承方式(基类Student不改)。可以写出私有派生类如下:class Student1:private Student/用私有继承方式声明public:void display_1()cout“age:“ageendl;cout“address:“addrendl;priva
16、te:int age;char addr12;,int main()Student1 stud1;stud1.display();/错误stud1.display_1();/正确stud1.age=18;/错误return 0;,结论:(1)不能通过派生类对象(如stud1)引用从私有基类继承过来的任何成员。(2)派生类的成员函数不能访问私有基类的私有成员,但可以访问私有基类的公用成员。在派生类外不能通过派生类对象调用私有基类的公用成员函数,但可以通过派生类的成员函数调用私有基类的公用成员函数(此时它是派生类中的私有成员函数,可以被派生类的任何成员函数调用)。,可将上面的私有派生类的成员函数定
17、义改写为void display_1()display();/调用基类的公用成员函数 coutage:ageendl;/派生类的私有数据成员coutaddress:addrendl;/派生类的私有数据成员main函数可改写为int main()Student1 stud1;stud1.display_1();/Student1类的公用函数 return 0;,由于私有派生类限制太多,使用不方便,一般不常使用。,11.4.3 保护成员和保护继承,protected 继承:基类的public成员,在派生类中成为protected 成员基类的protected成员,在派生类中成为protected
18、成员基类的private成员,在派生类中成为不可直接使用的成员,表11.3基类成员在派生类中的访问属性,保护成员可以被派生类的成员函数引用。但不能被实例函数引用。,例:class B1 int a;void f()couta;public:int b;void g()couta;protected:int c;void k()couta;,对派生类:class B2:public B1public:void df()couta;/coutb;coutc;f();/g();k();,对实例函数void main()B1 b1;coutb1.a;/coutb1.b;coutb1.c;/b1.f()
19、;/b1.g();b1.k();/,(1)在派生类中,成员有4种不同的访问属性:,表11.4派生类中的成员的访问属性,例11.3 在派生类中引用保护成员。#include#include using namespace std;class Studentpublic:void display();protected:int num;string name;char sex;,void Student:display()coutnum:numendl;coutname:nameendl;coutsex:sexendl;class Student1:protected Studentpublic:
20、void display1();private:int age;char addr 12;,void Student1:display1()/定义派生类公用成员函数 coutnum:numendl;/基类的保护成员,合法 coutname:nameendl;coutsex:sexendl;coutage:ageendl;/派生类的私有成员,合法 coutaddress:addrendl;int main()Student1 stud1;stud1.display1();stud1.num=10023;/错误,外界不能访问保护成员return 0;,在派生类的成员函数中引用基类的保护成员是合法的
21、。保护成员和私有成员不同之处,在于把保护成员的访问范围扩展到派生类中。注意:在程序中通过派生类Student1的对象stud1的公用成员函数display1去访问基类的保护成员num.name和sex,不要误认为可以通过派生类对象名去访问基类的保护成员。私有继承和保护继承方式很容易搞错,一般不常用。,11.4.4 多级派生时的访问属性,图11.9,如果有图11.9所示的派生关系:类A为基类,类B是类A的派生类,类C是类B的派生类,则类C也是类A的派生类。类B称为类A的直接派生类,类C称为类A的间接派生类。类A是类B的直接基类,是类C的间接基类。在多级派生的情况下,各成员的访问属性仍按以上原则确
22、定。,例11.4 多级派生访问属性。class Apublic:int i;protected:void f2();int j;private:int k;,class B:public A public:void f3();protected:void f4();private:int m;class C:protected Bpublic:void f5();private:int n;,class B:public:void f3();int i;protected:void f4();void f2();int j;private:int m;,class C:public:void
23、f5();protected:void f4();void f2();int j;void f3();int i;private:int n;,在派生类中是不能访问基类的私有成员的,私有成员只能被本类的成员函数所访问,毕竟派生类与基类不是同一个类。在多级派生时:采用公用继承方式,那么直到最后一级派生类都能访问基类的公用成员和保护成员。采用私有继承方式,经过若干次派生之后,基类的所有的成员已经变成不可访问的了。采用保护继承方式,在派生类外是无法访问派生类中的任何成员的。经过多次派生后,很难记住哪些成员可以访问,哪些成员不能访问。,常用的是公用继承!,11.5 派生类的构造函数和析构函数,用户在声
24、明类时可以不定义构造函数,系统会自动设置一个默认的构造函数。在设计派生类的构造函数时,希望在执行派生类的构造函数时,使派生类的数据成员和基类的数据成员同时都被初始化。解决这个问题的思路是:在执行派生类的构造函数时,调用基类的构造函数。,例11.5 简单的派生类的构造函数。#include#includeusing namespace std;class Student/声明基类Student public:Student(int n,string nam,char s)/基类构造函数 num=n;name=nam;sex=s;Student()/基类析构函数protected:/保护部分 in
25、t num;string name;char sex;,11.5.1 简单的派生类的构造函数,class Student1:public Student public:Student1(int n,string nam,char s,int a,string ad):Student(n,nam,s)age=a;addr=ad;void show()coutnum:numendl;coutname:nameendl;coutsex:sexendl;coutage:ageendl;coutaddress:addrendl;Student1()private:,调用基类构造函数,派生类新增的数据成员
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 继承与派生 继承 派生 PPT 课件
链接地址:https://www.31ppt.com/p-5568487.html