面向对象的程序设计:四、 类的继承与派生
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
11
派生类的定义
派生类构造函数及析构函数的构造规则
• 当基类构造函数没有参数,或没有显式定义构 造函数时,派生类可以不向基类传递参数,甚 至可以不定义构造函数。 • 若基类使用缺省或不带参数的构造函数,则在 派生类定义构造函数是可略去“基类构造函数 名(参数表)”,此时若派生类也不需要构造 函数,则可不定义构造函数。
Employee
由共性到个性
Transportation
Teacher
Officer
Worker
Flight
Vehicle
Ship
Car
Байду номын сангаас
Truck
Van
一般到特殊
基类
派生类
3
派生类的定义
派生类可以分为共有(public)派生类、私有(private) 派生类和保护(protected)派生类,其一般定义为:
18
多重继承
多继承中的二义性
• 如果多个基类中具有相同名字的成员,则派生类在引 用时就具有二义性。例如: class A{ public: void f();}; class B{ public: void f(); void g();}; class C: public A, public B { public: void g(); void h();}; main() { C a; a.f(); a.g();//二义性 }
运行结果 constructing base constructing derive destructing derive destructing base
13
派生类的定义
派生类构造函数及析构函数的构造规则
• 当基类的构造函数带有参数时,所有的派 生类都必须定义构造函数。有时所定义 的派生类的构造函数的函数体可以为空, 仅仅起参数传递作用。
8
派生类的定义
派生类对基类成员的访问规则:
内部访问:由类自己的函数访问; 类的对象访问:由类创建的对象访问; 外部访问:由友元等函数访问。一个类的友元自然可以访问该类的所 有成员。但一个外部的其他成员函数就不可能访问类的私有成员,只 能访问共有成员。 继承类对基类的访问规则:
公有派生类对基类的访问规则 数据类型 访问方式 内部访问 对象访问 私有成员 保护成员 公有成员 保护派生类对基类的访问规则 数据类型 访问方式 内部访问 对象访问 私有成员 保护成员 公有成员
5
派生类的定义
//定义派生类Car
#ifndef CAR_H #define CAR_H #include “vechicle.h”
Class Car:public vechicle //定义公有派生类 { Public: Car(int aw,int ats,float ap,int anc,int ahp):vechicle(aw,ate,ap) numberCylinders(anc),horsePower(ahp) { } //构造函数 void print( ); //打印函数 Private: int numberCylinders; //气缸数 Void main( ) int horsePower; //马力 { }; vechicle av(15000,60,3000); #endif Car ac(350,100,120,6,120); av.print();//调用基类函数 Void Car::print( ) ac.print();//派生类函数 { } vechicle::print( ); //调用基类的函数 cout<<“\n cylinders:”<<numberCylinders; cout<<“\n horsepower:”<<horsePower; 6 }
10
多重继承
多重继承的声明:
在C++语言中,声明具有两个以上基类的派生类与声明单继承的派生类 形式相似,只需将要继承的多个基类用逗号分隔开来,其声明的一般 形式为: Class 派生类名:派生类型1 基类名1,派生类型2 基类名2,…派生 类型n 基类名n { //语句 };
派生类型n:可为public、protected、private。
由共性到个性派生类的概念类具有共性和特殊性为了用语言表现类的共性和差异性继承是为了避免多次重复些同样的代码达到重用的目的
面向对象程序设计
第四章 类的继承与派生
1
主要内容:
派生类的概念 派生类的定义
多重继承
2
派生类的概念
• 类具有共性和特殊性,为了用语言表现类的共性和差 异性,继承是为了避免多次重复些同样的代码,达到重 用的目的。 • 继承是面向对象技术中一个重要的基本特征。 • 继承可以提高软件的重用性和可维护性;是多态性的 基础。
执行结果: Weight: 15000 pds Top speed: 60 mph Price: $3000 Weight: 350 pds Top speed: 100 mph Price: $120 Cylinders: 6 Horsepower: 120
派生类的定义
派生类的构造函数
分为显示调用构造函数和不显示调用构造函数。在派生类的构造函数中 不显示调用构造函数时;基类的构造函数是被调用了,如果有参数要传递 给基类的构造函数,就必须显示地调用基类的构造函数,同时,基类的参 数必须由派生类传递。 基类和派生类构造函数执行次序是:首先是基类的构造函数被执行,然 后在执行派生类的构造函数。析构函数的执行顺序与构造函数的调用顺序 正好相反。 具体语句: Car(int aw,int ats,float ap,int anc,int anp):vehicle(aw,ats,ap), numberCylinders(anc),horsePower(ahp) { }
19
多重继承
多继承中的二义性
• 为了避免二义性,可以在重名的成员前缀上类名。例 如: class A{ public: void f();}; class B{ public: void f(); void g();}; class C: public A, public B { public: void g(); void h();}; main() { C a; a.A::f(); a.B::g(); a.g();//对 }
Class base { public: …… private: …… protected: …… };
Class deriveName: public(or protected,private) base { Public: …… Private: …… Protected: …… };
4
派生类的定义
14
派生类的定义
构造函数与析构函数举例
• #include <iostream.h> class base{ int i; public: base(int n) {cout<<“constructing base\n”; i=n;} void showi() {cout<<i<<endl;} }; • 运行结果 class derive: public base{ int j; public: constructing base derive(int n):base(n) constructing derive {cout<<“constructing derive\n”;j=0;} 3 void showj() {cout<<j<<endl;} }; int main() 0 { derive op(3); op.showi();op.showj();return 0;}
12
派生类的定义
构造函数与析构函数举例
• #include <iostream.h> class base{ • public: base() {cout<<“constructing base\n”;} ~base() {cout<<“destructing base\n”;} }; class derive: public base{ public: derive() {cout<<“constructing derive\n”;} ~derive() {cout<<“destructing derive\n”;} }; main() { derive op; return 0;}
15
派生类的定义
派生类构造函数和析构函数的构造规则
• 如果派生类的基类也是一个派生类,则每个派生类只 负责其直接基类的构造,依次上溯。
• 由于析构函数是不带参数的,在派生类中是否要定义
析构函数与它所属的基类无关。
16
多重继承
多重继承的声明:
在C++语言中,声明具有两个以上基类的派生类与声明单继承的派生类 形式相似,只需将要继承的多个基类用逗号分隔开来,其声明的一般 形式为: Class 派生类名:派生类型1 基类名1,派生类型2 基类名2,…派生 类型n 基类名n { //语句 };
派生类型n:可为public、protected、private。
17
多重继承
多继承的访问特性
• 在多继承中,公有派生和私有派生对于基类成员在派生类中的可访 问性与单继承的规则相同。例如: #include <iostream.h> class X { int a; public: void setX(int x); void showX(); }; class Y { int b; public: void setX(int x); void showX(); }; class Z: public X, private Y { int c; public: void setZ(int x, int y); void showZ(); }; main() { Z obj; obj.setX(3); obj.showX(); obj.setY(4); obj.showY(); //错 obj.setZ(5,6); obj.showZ();}
7
派生类的定义
//file point.h Class point { Public: point( ); //缺省的构造函数 point(float x1,float y1); //带参数的构造函数 point(const point &p); //拷贝构造函数 void show( ); //打印显示 void move(foat x1,float y1); //移动点 Private: float x; float y; }; //file circle.h #include “point.h” Class circle::public point //公有派生类 { Private: float radius; Public: circle(float a,float b,float r):point(a,b) //基类的构造函数被显示调用 { radius=r; } void show( ) { point::show( );//调用基类的共有函数 cout<<“radius=“<<radius<<end1; } };
通过定义派生类,可以继承基类的数据和函数,同时又可以新 定义函数。
//定义基类Vechicle #include <iostream.h> Class vechicle { Public: vehicle(int aw,int ats,float ap):weight(aw),topSpeed(ats),price(ap){ } //构造函数 void print( ); //打印函数 Private: int weight; int topSpeed; float price; }; Void vechicle::print( ) { cout<<“\n weight:”<<weight<<“pds”; cout<<“\n top speed:’’<<topSpeed<<“mph”; cout<<“\n price: $’’<<price; }
no no
yes no
yes yes
no no
yes no
yes no
外部访问
友元ok
友元ok
yes
外部访问
友元ok
友元ok
yes
9
派生类的定义
派生类构造函数及析构函数的构造规则
• 派生类构造函数执行顺序
–先执行基类的构造函数 –再执行派生类的构造函数
• 派生类析构函数的执行顺序
–先执行派生类的析构函数 –再执行基类的析构函数