第七章 继承与派生
《C++语言程序设计》第7章 类的继承

this->h = h;
}
void move(float offX, float offY) {
Point::move(offX, offY);
}
float getX() const { return Point::getX(); }
float getY() const { return Point::getY(); }
第 7 章 类的继承
2
目录
类的继承与派生概述 类成员的访问控制 基类与派生类类型兼容规则 派生类的构造、析构函数 派生类成员的标识与访问 小结
3
公有单继承举例
• 设计一个汽车类Vehicle,包含的数据成员有:车轮个数wheels和 车重weight。
• 小车类Car继承汽车类Vehicle ,其中包含的新属性为载人数 passenger。
int main() { Rectangle rect; //定义Rectangle类的对象 rect.initRectangle(2, 3, 20, 10); //设置矩形的数据 rect.move(3,2); //移动矩形位置 cout << "The data of rect(x,y,w,h): " << endl; cout << rect.getX() <<", " //输出矩形的特征参数 << rect.getY() << ", " << rect.getW() << ", " << rect.getH() << endl; return 0;
public:
第七章派生与继承2

第七章派生与继承2/*7.4多继承与虚基类7.4.1多继承中的二义性问题解决方式1<对象名>.<基类名>::<成员名> //数据成员<对象名>.<基类名>::<成员名>(<参数名>) //成员函数*//*#include<iostream>using namespace std;class Base1{public:int date;void fun(){cout<<"Member of Base1"<<";base1="<<date<<endl;} };class Base2{public:int date;void fun(){cout<<"Member of Base2"<<";base2="<<date<<endl;} };class Derived:public Base1,public Base2{public:int date;void fun(){cout<<"Member of Derived"<<";Derived="<<date<<endl;} };int main(){Derived obj;obj.date=1;obj.fun();obj.Base1::date=2;obj.Base1::fun();obj.Base2::date=3;obj.Base2::fun();return 0;}*//*#include <iostream>using namespace std;class Base{public:int date;void fun(){cout<<"This is Base"<<"; base="<<date<<endl;}};class Derived11:public Base{public:int date;void fun(){cout<<"This is Derived11"<<"; Derived11="<<date<<endl;}};class Derived12:public Base{public:int date;void fun(){cout<<"This is Derived12"<<"; Derived12="<<date<<endl;}};class Derived2:public Derived11,public Derived12{public:int date;void fun(){cout<<"This is Derived2"<<"; Derived2="<<date<<endl;}};int main(){Derived2 obj;obj.date=1;obj.fun();//obj.Base::date=2;//obj.Base::fun();obj.Derived11::date=3;obj.Derived11::fun();obj.Derived12::date=4;obj.Derived12::fun();return 0;}*//*7.4.2虚基类的定义虚基类格式:class<类名>:virtual<继承方式><基类名>virtual与继承方式的位置无关,但是必须位于虚基类之前,切只对紧后面的基类名起作用。
第7章 继承性和派生类

{
派生类新定义成员
};
public表示公有继承
继承方式private表示私有继承
protected表示保护继承
继承方式规定了如何访问从基类继承的成员。继承方式缺省,隐含私有继承。
多继承的定义格式如下:
class派生类名:继承方式1基类名1,
继承方式2基类名2,…
{
派生类新定义成员
例7.9
#include<iostream.h>
class A
{public:
A( ){a=0;}
A(int i){a=i;}
void Print( ) {cout<<a<<”,”;}
private:
int a;
};
class B:public A
{public:
B( ){b1=b2=0; } //隐式调用A的构造函数
解决的方法:
(1)成员名限定法来消除二义性,例如:
c1.A::f( );或者c1.B::f( );
7.2单继承
7.2.1成员访问权限的控制
例7.2
#include<iostream.h>
class A
{public:
void f(int i){cout<<i<<endl;}
void g( ){cout<<”g\n”;}
};
class B:A
{public:
void h( ){cout<<”h\n”;}
7.2.2派生类的构造和析构函数
派生类继承了基类的成员,实现了原有代码的重用,这只是一部分,而代码的扩充才是最主要的,只有通过添加新的成员,加入新的功能,类的派生才有实际意义。基类的构造函数和析构函数不能被继承。在派生类中,如果对派生类新增的成员进行初始化,就必须由程序员针对实际需要加入新的构造函数。与此同时,对所有从基类继承下来的成员的初始化工作,还是由基类的构造函数完成,我们必须在派生类中对基类的构造函数所需要的参数进行设置。
c++7继承与派生

3
继承与派生问题举例
类 的 继 承 与 派 生
工具车
交通工具
汽车
小汽车
卡车
旅行车
轿车
面包车
4
继承与派生问题举例
类 的 继 承 与 派 生
动物
猴子
猫
鸟
狮子
5
虎
猎豹
类继承与派生问题举例 的 几何形状 继 承 与 派 生
圆
矩形
6
类继承与派生问题举例 的 雇员 继 承 与 兼职技术人员 管理人员 派 生
15
例7-2 私有继承举例
类 成 员 的 访 问 控 制
16
class Rectangle: private Point //派生类声明 {public: //新增外部接口 void InitR(float x, float y, float w, float h) {InitP(x,y);W=w;H=h;} //访问基类公有成员 void Move(float xOff, float yOff) {Point::Move(xOff,yOff);} float GetX() {return Point::GetX();} float GetY() {return Point::GetY();} float GetH() {return H;} float GetW() {return W;} private: //新增私有数据 float W,H; };
29
派 生 继承时的构造函数 类 的 基类的构造函数不被继承,派生类中需要 构 声明自己的构造函数。 造 声明构造函数时,只需要对本类中新增成 、 员进行初始化,对继承来的基类成员的初 析 始化,自动调用基类构造函数完成。 构 派生类的构造函数需要给基类的构造函数 传递参数 函 数
面向对象编程技术第七章派生与继承

1. 单继承:派生类只从一个基类派生。 2. 多继承:派生类从多个基类派生。 3. 多重派生:由一个基类派生出多个不同的派生类。 4. 多层派生:派生类又作为基类,继续派生新的类。
简化的继承体系图
返回
三种基本继承方式
1. 公有继承(public)
1) 基类的public和protected成员的访问属性在派生类中 保持不变;基类的private成员不可访问(类内)
}
三种继承方式之间的比较
返回
?
派生类的构造与析构函数
一、构造函数
1. 基类的构造函数不被继承,需要在派生类中自行 声明
2. 初始化完成:
1. 基类成员:基类构造函数完成 2. 内嵌对象成员 3. 新增成员
顺序的思考: 有它的现实
原形么?
派生类的构造函数
格式:派生类名::派生类名(参数总表):基类名1(参数),
2. 我定义了一个描述点的类,如何在定义一个描述
矩形的类?
现实思维模
.
.W
?
式
H
类的继承与派生的提出
▪ 继承的目的:实现数据、代码的重用。 ▪ 派生的目的:当新的问题出现,原有程序无法解决
(或不能完全解决)时,需要对原有数据、代码进 行改造。
返回
派生类的定义与相关概念
定义格式:class 派生类名:继承方式1 基类名1,…,继承方 式n 基类名n
B1 memberB1; B2 memberB2; B3 memberB3; };
void main( ) { C obj(1,2,3,4); }
认真思考并回 答其输出结果?
constructing B2 2 constructing B1 1 constructing B3 * constructing B1 3 constructing B2 4 constructing B3 * Press any key to continue
c++7继承与派生

1. 可以访问 f1( )和j1, 而不可以访问 i1 2. 可以访问 f1( ),而不可以访问 i1和 j1 3. 可以访问直接基类中的 f2( )和 j2以及间接基类中 的 f1( )和 j1,而不可以访问 i2和 i1 4. 可以访问直接基类中的 f2( )和间接基类中的 f1( ), 其它均不可以
A
B C
输入设备
键盘 鼠标 扫描仪
B. 派生类是基类定义的延续(虚函数) C. 派生类是基类的组合(多继承)
四、 单继承中成员访问权限
class A { public: void f1( ); protected:int j1; private: int i1; }; class C:public B { public: void f3( ); }; class B:public A { public: void f2( ); protected: int j2; private: int i2; };
void main() { A oba; cout<<oba.max<<endl; //合法吗?5 cout<<oba.min<<endl; //合法吗?6
B obb; cout<<obb.max<<endl; //合法吗?7 cout<<obb.min<<endl; //合法吗?8
}
//1、3、4合法;其余不合法
换句话说:
保持已有类的特性而构造新类的过程称为继承。 在已有类的基础上新增自己的特性而产生新类的 过程称为派生。
继承的思想方法是人类常用的分析问题的方 法——演绎
动物
猴子
猫
鸟
狮子
C语言程序设计第七章继承性和派生类.

};
第七章
五、基类与派生类的关系:
1、派生类是基类的具体化: 基类是对若干个派生类的抽象,而派生类是基类 的具体化。基类抽取了它的派生类的公共特征,而派 生类通过增加行为将抽象类变为某种有用的类型。
输入设备
键盘
鼠标器
数字化仪
第七章
2、派生类是基类定义的延续: 先定义一个抽象基类,该基类中有些操作并未实 现。然后定义非抽象的派生类,实现抽象基类中定义的 操作。这时,派生类是抽象的基类的实现,即可看成是 基类定义的延续。这也是派生类的一种常用的方法。 3、派生类是基类的组合: 在多继承时,一个派生类有多于一个的基类,这时派 生类将是所有基类行为组合。
第七章 A's destructor called. B's destructor called. A's destructor called. A's destructor called
第五节
子类型和赋值兼容规则
第七章
一、子类型:
有一种类型A,它至少包含有另一种类型B的所有 行为,则称类型A是类型B的子类型。子类型的关系是 不可逆的。
第七章 } void main() { B bb[2]; bb[0]=B(1,2,5); bb[1]=B(3,4,7); for(int i=0;i<2;<i++) bb[i].Print(); }