第章继承与派生newppt课件.ppt
《第章继承与派生newppt课件.ppt》由会员分享,可在线阅读,更多相关《第章继承与派生newppt课件.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+中可重用
2、性是通过继承(inheritance)这一机制来实现的。继承是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 派生类的声明方式,派生类分为两大部分: 一部分是从基类继承来的成员 另一部分是在声明派生类时增加的部分 每一部
4、分均分别包括数据成员和成员函数。,11.3 派生类的构成,构造一个派生类包括以下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 A int x,y; public: void f(); void g(); ; class B : public A int z;
6、 public: void h(); ;,在C+中对派生类有以下几点规定: 派生类除了拥有基类的所有成员(基类的构造函数和赋值操作符重载函数除外)外,也可以具有新的成员。,class A int x,y; public: void f(); void g(); ; class B : public A int z; public: void h(); ;,void main() B b; b.f( ); /A类中的 f b.g( ); /A类中的g b.h( ); /B类中的h ,派生类的定义用于描述派生类与基类的差别。派生类中可以给出新的成员,也可以对基类的成员进行重定义。如果在派生类中对基
7、类的某个成员进行重定义,则在派生类中对该成员的访问是针对派生类中重定义的成员。,class B : public A int z; public: void f(); void h() f( ); /B类中的f g( ); /A类中的g ; void main( ) B b; b.f( ); /B类中的 f b.g ( ); /A类中的g b.h( ); /B类中的h ,派生类成员名的作用域嵌套在基类的作用域中,对于基类的一个成员,如果派生类中没有定义与其同名的成员,则该成员名在派生类的作用域内可见,否则,该成员名在派生类的作用域内不直接可见,如果要使用,必须用基类名受限。例:,class B
8、 : public A int z; public: void f( ); void h( ) f( ); /B类中的f A:f( ) /A类中的f ; void main( ) B b; b.f( ); / B 类中的 f b.A:f( ); /A类中的f ,即使派生类中定义了与基类同名但参数不同的成员函数,基类的同名函数在派生类中的作用域中也是不直接可见的。例:,class B : public A int z; public: void f(int); void h( ) f(1); /Ok f( ); / A:f( ) / Ok ; void main( ) B b; b.f(1);
9、/ Ok b.f( ); / b.A:f( ); / Ok ,定义派生类时一定要见到基类的定义,否则编译程序无法确定派生类对象需占多大内存空间以及派生类中对基类成员的访问是否合法。例:,class A; class B : public A int z; public: void h( ) g( ); /Error没有g的原型 ; B b; / Error无法确定 b 所需空间 ,如果在派生类中没有显式说明,基类的友元不是派生类的友元;如果基类是另一个类的友元,而该类没有显式说明,则派生类也不是该类的友元。 派生类不能直接访问基类的私有成员,必须要通过基类的非私有成员函数来访问基类的私有成员。
10、例:,class A int x,y; public: void f( ); void g( )x; ; class B : public A int z; public: void h( ) x /Error, x为基类的私有成员 g( ); /Ok, 通过函数g访问基类的私有成员x ;,在派生类中对基类成员的访问 一个类有两种用户:实例用户和派生类。例: 一个类存在两个对外接口 给实例用户使用:由类的public成员构成 提供给派生类使用:由类的public和protected成员构成,class A ; class B : public A /派生类 ; void f( ) /实例用户
11、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 / Error a.y / Error a.f( ); / Ok ;,类的聚集:一个类只有一个接口,即类的实例用户接口。例:以继承和聚集实现的代码重用。,class A public : void f(); void g(); ; class B : public A public : void h(); ;,clas
12、s 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 访问公有基类的成员。
13、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
14、name: nameendl; /引用基类的私有成员,错误 cout sex: sexendl; cout age: ageendl; /引用派生类的私有成员,正确 cout address: addrendl; /引用派生类私有成员,正确 private: int age; char addr12; ;,结论: 由于基类的私有成员对派生类来说是不可访问的,因此在派生类中的display_1函数中直接引用基类的私有数据成员num,name和sex是不允许的。 只能通过基类的公用成员函数来引用基类的私有数据成员。,可以将派生类Student1的声明改为: class Student1: publ
15、ic Student /以public方式声明派生类Student1 public: 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“ addre
16、ss: “addrendl;,void get_value_1( ) get_value( ) ; Cinageaddr;,private继承: 基类的public成员, 在派生类中成为private 成员 基类的protected成员, 在派生类中成为private成员 基类的private成员, 在派生类中成为不可直接使用的成员,11.4.2 私有继承,表11.1私有基类在派生类中的访问属性,图11.7表示了各成员在派生类中的访问属性。,例11.2 将例11.1中的公用继承方式改为用私有继承方式(基类Student不改)。 可以写出私有派生类如下: class Student1: priv
17、ate Student/用私有继承方式声明 public: void display_1( ) cout“age: “ageendl; cout“address: “addrendl; private: int age; char addr12; ;,int main( ) Student1 stud1; stud1.display(); /错误 stud1.display_1( ); /正确 stud1.age=18; /错误 return 0; ,结论: (1) 不能通过派生类对象(如stud1)引用从私有基类继承过来的任何成员。 (2) 派生类的成员函数不能访问私有基类的私有成员,但可以
18、访问私有基类的公用成员。 在派生类外不能通过派生类对象调用私有基类的公用成员函数,但可以通过派生类的成员函数调用私有基类的公用成员函数(此时它是派生类中的私有成员函数,可以被派生类的任何成员函数调用)。,可将上面的私有派生类的成员函数定义改写为 void display_1( ) display(); /调用基类的公用成员函数 coutage: ageendl; /派生类的私有数据成员 coutaddress: addrendl; /派生类的私有数据成员 main函数可改写为 int main( ) Student1 stud1; stud1.display_1( ); /Student1类的
19、公用函数 return 0;,由于私有派生类限制太多,使用不方便,一般不常使用。,11.4.3 保护成员和保护继承,protected 继承: 基类的public成员, 在派生类中成为protected 成员 基类的protected成员, 在派生类中成为protected 成员 基类的private成员, 在派生类中成为不可直接使用的成员,表11.3基类成员在派生类中的访问属性,保护成员可以被派生类的成员函数引用。但不能被实例函数引用。,例: class B1 int a; void f( )couta; public: int b; void g( )couta; protected: i
20、nt c; void k( )couta; ;,对派生类: class B2: public B1 public: void df( ) couta; / coutb; coutc; f( ); / g( ); k( ); ;,对实例函数 void main( ) B1 b1; coutb1.a;/ coutb1.b; coutb1.c; / b1.f( ); / b1.g( ); b1.k( ); / ,(1) 在派生类中,成员有4种不同的访问属性:,表11.4派生类中的成员的访问属性,例11.3 在派生类中引用保护成员。 #include #include using namespace
21、std; class Student public: void display( ); protected : int num; string name; char sex; ;,void Student:display( ) coutnum: numendl; coutname: nameendl; coutsex: sexendl; class Student1: protected Student public: void display1( ); private: int age; char addr 12; ;,void Student1:display1( ) /定义派生类公用成员
22、函数 coutnum: numendl; /基类的保护成员,合法 coutname: nameendl; coutsex: sexendl; coutage: ageendl; /派生类的私有成员,合法 coutaddress: addrendl; int main( ) Student1 stud1; stud1.display1( ); stud1.num=10023; / 错误,外界不能访问保护成员 return 0; ,在派生类的成员函数中引用基类的保护成员是合法的。保护成员和私有成员不同之处,在于把保护成员的访问范围扩展到派生类中。 注意: 在程序中通过派生类Student1的对象s
23、tud1的公用成员函数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的间接基类。在多级派生的情况下,各成员的访问属性仍按以上原则确定。,例11.4 多级派生访问属性。 class A public: int i; protected: void
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 继承 派生 newppt 课件
链接地址:https://www.31doc.com/p-2572305.html