第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生第九讲 派生与继承性第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生派 生 类 (derived class)
为什么引入派生类? 自然地表示现实世界,是复杂的系统层次化,提高代码的重用性,增强语言功能,提高软件开发效益,
例如关于雇员和车辆的层次关系,
Teacher(教师 ) Officer(行政 ) Worker(工人 )
Employee(雇员 )
Car(汽车 ) Sportscar(赛车 )
Vehicle(车辆 )
第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生派生类定义方式?
class base
{ public:
……
protected:
……
private:
…… };
public
class derivedName,protected base{..}
private
public,protected 和 private分别表示公有继承、保护继承和私有继承第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生例 1 基类车辆 vehicle.h (因篇幅所限,我们将类的实现放到头文件之中)
#include<iostream.h>
class vehicle {
public:
private:
};
vehicle(int aw,int ats,float ap)
:weight(aw),topspeed(ats),price(ap) { }
void print( ) {
cout << "\n weight:" << weight << "pds";
cout << "\n top speed:" << topspeed << "mph";
cout << "\n price,$ "<< price;
int weight; //重量
int topspeed; //最高速度
float price; //价格第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生
//公有派生类汽车 car.h
#include " vehicle.h"
class car,public vehicle {
public:
private:
};
car(int aw,int ats,float ap,int anc,int ahp)
:vehicle(aw,ats,ap),numbercylinders(anc)
,horsepower(ahp) { }
void print( ) {
vehicle::print( ); //调用基类的函数
cout << "\n cylinders:" << numbercylinders;
cout << "\n horsepower:" << horsepower;
int numbercylinders; //汽缸数
int horsepower; //马力第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生
//应用程序 main.cpp
#include " vehicle.h "
void main ( )
{ vehicle av(15000,60,300000); //创建对象
car ac(3500,100,12000,6,120);//创建对象
av.print( ); //调用基类函数
ac.print( ); //调用派生类函数
}
结果,weight,15000 pds
top speed,60 mph
price $300000.00
weight,3500 pds
top speed,100 mph
price $12000.00
cylinders,6
horsepower,120
第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生例 1 有关内容总结
1,在已有的类中加入新功能而创建的类称为原有类的派生类。
2,继承的方式有三种,公有、保护、私有 。
一般为公有或保护
3,继承类具有基类的所有成员,并可对已有的成员进行重新定义。在派生类中访问基类的函数用,:表明,如在 car 中有:
vehicle::print( );
4,问题?派生类 的构造函数的定义?
派生类对基类的访问权限?
第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生派生类与基类的构造函数
1。派生类的构造函数自动执行基类的构造函数,且基类的构造函数先执行。
2。派生类的构造函数可不显式地写出基类的构造函数,此时调用基类的无参数构造函数,但若要传递参数,必须写出如,car(int aw,int ats,float ap,int anc,int ahp)
:vehicle(aw,ats,ap),numbercylinders(anc)
,horsepower(ahp) { }
创建对象:
vehicle av(15000,60,300000);
car ac(3500,100,12000,6,120);
第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生派生类对基类成员的访问规则
3,外部访问,由友元、继承类函数等访问访问有三种类型:
1,内部访问,由类自己的函数访问,如前例类 vehicle 中的函数 print
void print( ) {
cout << "\n weight:" << weight << "pds";
cout << "\n top speed:" << topspeed << "mph";
cout << "\n price,$ "<< price; }
2,类的对象访问,由类创建的对象访问。
vehicle av(15000,60,300000); //创建对象
av.print( ); //调用基类函数第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生公有派生类对基类成员的访问规则
1,基类的私有数据。
内部访问?OK
对象访问?NON
外部访问?友元 OK,继承类 NON
2,基类的保护数据。
内部访问?OK
对象访问?NON
外部访问?友元 OK,继承类 OK
3,基类的公有数据。
内部访问?OK
对象访问?OK
外部访问?友元 OK,继承类 OK
第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生例 2,类 point 和 cercle
//save as point.h
class point
{ public,//公有成员
point( ); //缺省 构造函数
point(float x1,float y1);//带参 数构造函数
point( const point &p); //拷贝 构造函数
void show( ); //打印 显示点
void move(float x1,float y1); //移动点
private,//私有成员
float x; //点的横坐标
float y; //点的纵坐标
}; //类定义结束第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生
//save as point.cpp
#include " point.h "
point::point( ) { x=0; y=0; } //缺省构造函数
point::point(float x1,float y1)//参数构造函数
{x=x1; y=y1;}
point::point(const point &p) //拷贝构造函数
{ x=p.x;
y=p.y; }
void point::show( )
{ cout <<?Point(x,y)=(? << x
<<?,? << y <<?)? << endl; }//显示点
void point::move(float x1,float y1)//移动点
{
x=x+x1; y=y+y1;
}
第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生
//继承类 circle
#include<iostream.h>
#include "point.h,
class circle::public point
{
public:
circle(float a,float b,float r):
point(a,b) { radius = r; }
void show( )
{ cout << x << "," << y << endl;
point::show( );
cout << " radius= " << radius << endl; }
};
private:
float radius;
//
第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生
//save as main.cpp
#include " circle.h "
void main( )
{ circle c1(2,2,4); //调用参数构造函数
c1.show( ); //打印圆的半径和圆心
cout << c1.radius;
cout << x;
}
结果,Point(x,y)=(2,2)
radius=4
// 不能访问私有数据
// 不能访问私有数据第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生例 2 有关内容总结
1,明确继承类构造函数与基类构造函数的关系及实现。
2,明确内部访问、对象访问与外部访问的权限。特别是继承类对基类成员的访问。
3,继承类具有基类的所有成员,并可对已有的成员进行重新定义。在派生类中访问基类的函数用,:表明,如在 car 中有:
point::show( );
4,面向对象技术中的基本特征:类与继承在 C++中的实现第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生多重继承问题的提出?单继承中,基类只有一个,
如果一个类由多个基类继承而来,该任何定义?
teacher(教师 ) sudentr(学生 )
data_rec(信息记录 )
t_postgra(在职研究生 )
Postgra(研究生 )
例如学校人员分类的层次关系:
第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生问题,teacher 和 student都是 data_rec的继承类,它们都有基类的所有成员,即有一个基类成员的拷贝。 t_postgra分别是
teacher 和 student的继承类,所以,它具有两者的一个拷贝,即有两个 data_rec的拷贝
==,数据冗余解决的办法,虚基类对多继承的派生类,它将只保持一个基类的成员拷贝实现办法,在继承的基类前加关键字 virtual
class devried::virtual baseClass…...
第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生例 3:学校人员分类描述,有类 data_rec,
teacher,student,postgra,tpost,文件为 univ.h
#include<iostream.h>
#include<string.h>
class data_rec
{
public:
data_rec( ) { name=null; }
void insert_name( char *na)
{ delete [] name;
name=new char[strlen(na)+1];
strcpy(name,na); }
void print ( ) { cout << "\n name:" << name; }
private:
char *name; };
第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生
//定义派生类 student
class student::virtual public data_rec
{ public:
student( ):data_rec( ) { id=0; } //构造函数
void insert_id(int pid) { id=pid;}
void print ( )
{
data_rec::print( ); //访问基类的函数
cout << "\n id=" << id;
}
private:
int id;
};
第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生
//定义派生类 teacher
class teacher::virtual public data_rec
{ public:
teacher( ):data_rec( ) {sal=0;} //构造函数
void insert_sal(float psal) { sal=psal;}
void print ( )
{
data_rec::print( ); //访问基类的函数
cout << "\n sal=" << sal;
}
private:
float sal;
};
第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生
//定义派生类 postgra
class postgra:,public student
{ public:
postgra( ):student( ) {dn=null;} //构造函数
void insert_dn(char *p)
{ delete [] dn;
dn=new char[strlen(p)+1];
strcpy(dn,p); }
void print ( )
{ data_rec::print( ); //访问基类的函数
cout << "\n dept name=" << dn; }
private:
char *dn;
};
第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生
//定义派生类 tpost
class tpost:,public teacher,public postgra
{ public:
tpost( ):teacher( ),postgra( ) { } //构造函数
void print ( )
{ teacher::print( ); //访问基类的函数
postgra::print( ); } };
第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生
//应用程序
#include univ.h
void main( )
{ teacher tobj; //定义类 teacher 的对象
tpost tpobj; //定义类 tpost 的对象
tobj.insert_name(Liming); //访问 data_rec的函数
tobj.insert_sal(1000); //访问 teacher自己的函数
tpost.insert_name(Xuli); //访问 date_rec的函数
tpost.insert_id(99410); //访问类 student 的函数
tpost.insert_dn(Comp); //访问类 postgra的函数
tobj.print( ); //访问派生类自己的函数
tpobj.print( ); //访问派生类自己的函数
}
结果,name=Liming
sal= 1000
name= Xuli
id= 99410
dept name=Comp
第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生课 堂 总 结
2 有三种派生类型:公有、保护和私有。
对基类成员的访问有一定的规则。
1 基类和派生类体现了类之间的层次关系。
派生类具有基类的所有成员。
3 派生类的构造函数自动执行基类的构造函数,且基类的构造函数先执行。基类构造函数的参数由派生类传递。
4 继承类具有基类的所有成员,并可对已有的成员进行重新定义。在派生类中访问基类的函数用,:表明。
5 可定义多重派生类。且可利用虚基类使派生类只保持一个基类的成员拷贝。
第 7章 派生与继承性
7.1 派生类
7.2 多重继承
7.3 类模板的派生作 业
1。根据课堂定义的 point 类,定义矩形类。
2。在 data_rec类下定义派生类 worker,有私有数据“工资”,再定义 worker 和
student的多派生类“在职学生” wstudent,
它们都有一个缺省构造函数和 print( )函数,请用虚基类消除数据冗余。
3。教材 p237页第 7题的 7.1小题。