5 类之继承性与派生类
继承与派生
4.1 继承和派生的概念
在软件开发过程中,在定义特殊类时,不需把它的一 般类已经定义过的属性和服务重复地书写一遍,只需要声 明它是某个类的特殊类,并定义它自己的特殊属性和服务。 这将明显地减轻开发工作的强度。 4.1.2 继承的作用 面向对象程序设计的继承性使得大型应用程序的维护 和设计变得更加简单。一方面,大型应用程序设计完成并 交付使用后,经常面临用户的需求发生变化,程序功能需 要扩充等问题。这时程序的修改需要非常谨慎,因为某个 局部的修改可能会影响其他部分,而一个正在使用中的系 统要进行全面的测试,既费时间又有很多实际的困难。另 一方面,一个新的应用系统程序设计在许多方面会和以前 设计过的某个或某些系统的模块非常类似,怎样加快大型 应用程序的开发速度,重用这些已经开发成功的程序模块, 一直是软件设计中迫切需要解决的问题。
4.2 派生类
C++语言派生类多重继承的定义格式如下: class <派生类名>:[继承方式1] [<基类名1>],[继承 方式2] [<基类名2>],…, [继承方式n] [<基类名n>] { <派生类成员变量和成员函数定义> }; 通常,在多重继承时,继承方式设计成一致的形式。 如继承方式均设计成public,或均设计成private。
901数据结构和程序设计
二、 考试的内容及比例
数据结构考试的内容包括:( 占总分50%)
1、 线性表、顺序表、链表的定义、特点、存储结构及相关的基本算法
2、 栈的定义、特点、顺序与链式存储表示、基本算法;栈的应用;队列的定义、特点;链队列、循环队列相关的定义、特点、基本算法;栈与递归的实现
天津大学全国统考应用型硕士生入学考试
业务课程大纲
课程编号:901 课程名称:数据结构和程序设计
一、 考试的总体要求
本考试内容由两部分组成,数据结构和程序设计,各占总分的
50%。
数据结构是计算机科学与技术专业基础课,要求学生掌握基本的数据结构及相关的存储方式、基本运算、算法和应用,并能运用盒图、结构化语言、类C、高级语言(C或C++)等方法之一编写算法。
3、 广义表的定义及存储结构
4、 二叉树的定义、性质及存储结构;遍历二叉树定义、过程及其算法;二叉树的应用;森林与二叉数的转换;哈夫曼树及其应用;与二叉树应用相关的递归算法
5、 图的定义、存储结构;图的遍历过程及算法;最小生成树构造过程及算法;拓扑排序过程及算法;关键路径相关内容;最短路径相关内容;与图的应用相关的递归算法
比例: 实做题(60%)
算法设计题(40%)
程序设计部分:
包括3类题型:程序填空,写程序结果和程序设计。
程序填空题:本题型给出程序的功能描述与少量提示,考生填写缺少的程序部分,使得程序完整,并且实现描述的功能。
本题型为20分,2---4个题。
派生类(继承)的概念
4.1 派生类的概念
上一节 上一页 下一页 下一节
4.1.2 派生类的声明
1.声明派生类的一般格式为: class 派生类名:继承方式 基类名 { //派生类中新增或改写的数据成员和成员 函数 }; 2.继承方式 继承方式可以是public、private和protected,分 别表示公有、私有和保护继承。 系统默认的继承方式为私有(private)继承。
4.1 派生类的概念
class student:public person{ int score; int grade; public: student(……); void print( ) {cout<<name<<“ “<<age <<“ “<<sex<<“ ”<<score <<“ “<<grade<<endl;} }; 从基类person中继承来的私 有数据成员name、age、sex 在派生类中不能直接访问, 如何解决?
类2
下一页 下一节
4.1.2 派生类的声明
引例:构造学生类和雇员类
class student{ char name[10]; int age; char sex; int score; int grade; public: student(……); void print( ) {cout<<name<<“ “ <<age<<“ “<<sex<< “ ”<<score<<“ “<< grade<<endl;} };
protected
C++第5章习题参考答案
1.什么是类的继承与派生?继承性是面向对象程序设计的第二个重要特性,通过继承实现了数据抽象基础上的代码重用。
继承是对许多问题中分层特性的一种自然描述,因而也是类的具体化和被重新利用的一种手段,它所表达的就是一种对象类之间的相交关系。
它使得某类对象可以继承另外一类对象的特征和能力。
继承所具有的作用有两个方面:一方面可以减少代码冗余;另一方面可以通过协调性来减少相互之间的接口和界面。
通过继承方式定义的子类也称为派生类。
2.类的三种继承方式之间的区别是什么?类的继承方式有public(公有)继承、protected(保护)继承和private(私有)继承三种。
对于不同的继承方式,会导致基类成员原来的访问属性在派生类中有所变化。
表5.1列出了不同继承方式下基类成员访问属性的变化情况。
表5.1 不同继承方式下基类成员的访问属性说明:该表第1列给出3种继承方式,第1行给出基类成员的3种访问属性。
其余单元格内容为基类成员在派生类中的访问属性。
从表中可以看出:(1) 基类的私有成员在派生类中均是不可访问的,它只能由基类的成员访问。
(2) 在公有继承方式下,基类中的公有成员和保护成员在派生类中的访问属性不变。
(3) 在保护继承方式下,基类中的公有成员和保护成员在派生类中均为保护的。
(4) 在私有继承方式下,基类中的公有成员和保护成员在派生类中均为私有的。
需要注意的是:保护成员与私有成员唯一的不同是当发生派生后,处在基类protected区的成员可被派生类直接访问,而私有成员在派生类中是不可访问的。
在同一类中私有成员和保护成员的用法完全一样。
3.派生类能否直接访问基类的私有成员?若否,应如何实现?派生类不能直接访问基类的私有成员。
具体实现方式:(1) 在类定义体中增加保护段为了便于派生类的访问,可以将基类私有成员中需提供给派生类访问的部分定义为保护段成员。
保护段成员可以被它的派生类访问,但是对于外界是隐藏起来的。
这样,既方便了派生类的访问,又禁止外界对它的派生类访问。
基类和派生类
5
(1)公有继承(public)
当类的继承方式为公有继承时,基类的公有和保 护成员的访问属性在派生类中不变,而基类的私有 成员不可访问,
即基类的公有成员和保护成员被继承到派生类中 仍作为派生类的公有成员和保护成员,派生类的其 他成员可以直接访问它们。
具体赋值规则如下: 派生类的对象可以赋值给基类对象。 派生类的对象可以初始化基类对象的引用。 派生类对象的地址可以赋给指向基类对象的 指针。
15
例如: class A{...};
class B: public A
{void fun() {...}}; A a; B b; a=b; //将对象b中所含类A成员的值赋给对象a A &a1=b; //用派生类对象初始化基类对象的引用 A *pa =&b;
22
基类名1,继承方式2 基类名2,… {…} ;
{ 派生类类体
class C : public
};
A , private B
多重继承允许一个派生类同时继 {…} ; // C 公有
承多个基类中的成员,支持了软件 继承 A,私有继
的重用性,但也可能带来大量的二 承 B
义性问题。 17
复合与继承在软件渐增式开发中的应用
10
3.在派生类中重定义基类的函数
派生类自动继承了基类中定义的数据成员和成员函数。 如果派生类认为基类中某个成员函数的实现不能满足需 要,可以在派生类中重新定义该函数。
重定义基类的成员函数需要使用和该函数相同的函数 名和参数列表,如果参数列表不同,就是函数重载而不 是函数的重定义了。
第5章 继承和派生类
2010/9/18
第5章 继承和派生类
程序运行结果: x=4 y=5 l=6 w=8 程序分析: 通过公有继承方式,从BaseClas类得到DerivedClass类。 派生类DerivedClass只有一个基类,所以是单继承。基类 BaseClass定义了两个数据成员,3个成员函数。派生类 DerivedClass定义了两个数据成员,3个成员函数。通过 继承,派生类DerivedClass拥有4个数据成员:x、y、l和 w,6个成员函数:setx ( )、sety ( )、setl ()、setw ( )、 displayxy ( )、displaylw( )。
2010/9/18
面象对象程序设计
第5章 继承和派生类
class Father:private Grandfather //中间类:Grandfather的 公有派生类, //Son的基类 { public: void test() { b1=10; //可以访问,因b1改为private b2=20; //可以访问,因b2改为private b3=30; //不可访问, 因b3改为不可访问 } };
2010/9/18
面象对象程序设计
第5章 继承和派生类
5.1.2 继承的种类
在C++语言中,一个派生类既可以从一个基类派生,也可 以从多个基类派生。从一个基类派生的继承被称为单继承。 单继承形成的类层次是一个倒挂的树,如图5.2所示。从 多个基类派生类的继承被称为多继承。多继承形成的类层 次是一个有向无环图(DAG),如图5.3所示。在图5.2中, 输入设备是基类,从它派生出了3个派生类:键盘类、鼠 标类和扫描仪类。在图5.3中,从教师类和干部类派生出 校长类,即校长类有两个基类。
第5章 派生类与继承
void print();
};
print();
};
//定义一个基类 class person{ protected: char name[10]; int age; char sex; public: //…… }; //定义一个派生类 class employee:public person { protected: char department[20]; float salary; public: //…… };
当类的继承方式为私有继承时,基类的public成员和 protected成员被继承后作为派生类的private成员,派生类 的其他成员可以直接访问它们,但是在类外部通过派生类的 对象无法访问。
基类的private成员在私有派生类中是不可直接访问的, 所以无论是派生类成员还是通过派生类的对象,都无法直接 访问从基类继承来的private成员,但是可以通过基类提供 的public成员函数间接访问。 例5.1一个私有继承的例子
由于派生类继承了基类的成员,派生类的构造 函数需要调用基类的构造函数对其中定义于基 类的数据成员进行初始化。 给基类构造函数传递实际参数是通过向派生类 构造函数传递实际参数以及初始化列表来间接 实现传递的。
5.2.1 派生类构造函数和析构函数的执行顺 序 通常情况下,当创建派生类对象时, 首先执行基类的构造函数,随后再执行 派生类的构造函数; 当撤消派生类对象时,则先执行派生 类的析构函数,随后再执行基类的析构 函数。
例5.3 公有继承的访问规则
表5-3 公有继承的访问规则
基类成员 内部访问 对象访问 Private成员 不可访问 不可访问 public成员 可访问 可访问 protected成员 可访问 不可访问
5.2 基类和派生类
5.2 基类和派生类在C++中,当一个类被其他类继承时,被继承的类称为基类(base class)。
继承其他类特性的类称为派生类(derived class)。
从本质上看,基类是具有一个类集合中的公共特性,派生类在继承基类特性的同时可以加入自己独有的特性。
基类与派生类之间反映出下述三种不同的现象:(1)派生类是基类的具体化。
即模拟概念层次,表示“is-a”的关系。
(2)派生类是基类的延迟定义。
可以定义一个抽象基类,定义一些操作,使它们服从一定的协议,但许多可能并未实现,然后定义非抽象的派类,实现抽象基类中定义的行为。
这时派生类不是基类的具体化,而是抽象类的实现。
在JA V A中,有专门的纯虚类,称为接口,其作用就是为不同的类提供一个统一的接口,同时间接实现多继承(JA V A不支持多继承)。
(3)派生类是基类的结合。
当一个派生类有多于一个的基类时,它们组合在一起形成具有所有基类行为的类型。
这时要注意,不要用继承表达聚合关系。
5.2.1 基类与派生类的说明先看一个例子。
[例5.1] 派生类的说明EX5_1.CPP。
继承基类的派生类定义的一般形式:class derived_class_name:access_specifier base_class_name{……};其中access_specifier可以是3个关键字之一:public、private(默认值)或protected。
派生类也称为子类、导出类。
它具有下述特点:(1)可在基类所提供有基础上包含新成员;(2)可在自己类中隐藏基类的任何成员;(3)为新类重新定义基类中的函数;[例5.2] 子类的特点EX5_2.CPP。
5.2.2 派生类的继承权与访问域派生类的继承权如果不能有效在加以限制,就不能按照实际情况表达求解问题的复杂性。
因此访问权限是一个很重要的问题。
(1)对于基类的私有成员,派生类及派生类的使用者无权访问。
(2)对于基类的公有成员,则按派生类的定义,分为三种情况:①私有派生,继承基类的公有成员作为自己的私有成员,这些成员只能被派生类的成员函数访问。
继承与派生类答案
继承与派生类知识要点1.掌握继承和派生的定义,派生类的定义方法。
(1)掌握继承的两种类型:单继承和多继承。
(2)掌握private,public,protected三种继承方式的特点。
继承方式决定了基类中的成员在派生类中的属性。
三种继承方式的共同点:基类的private成员在派生类中不可见。
区别:对于私有继承,基类的public、protected成员在派生类中作为private成员;对于公有继承,基类的public、protected成员在派生类中访问属性不变;对于保护继承,基类的public、protected成员在派生类中作为protected成员。
(3)掌握派生类中的构造函数和析构函数的使用。
基类的构造函数和析构函数不能继承,所以必要时在派生类中定义自己的构造函数和析构函数。
派生列的构造函数完成基类中新增数据成员和基类数据成员的初始化,基类数据成员的初始化通过基类构造函数来实现。
(4)掌握派生类的同名覆盖规则。
(5)掌握赋值兼容规则。
基类对象可以使用公有派生类对象来代替,包括:派生类对象可以赋值给基类对象;派生类对象可以初始化基类对象的引用;基类类型指针可以指向派生类对象。
2.掌握多重继承的概念、定义方法、多重继承派生类构造函数的执行顺序。
派生类构造函数的执行顺序是先执行所有基类的构造函数(顺序按照定义派生类时指定的各基类顺序),在执行对象成员所在类的构造函数(顺序按照他们在类中的声明顺序),最后执行派生类构造函数体中的内容。
3.掌握虚基类的概念和定义方法。
在多重继承中,如果多条继承路径上有一个公共的基类,则在这些路径的汇合点上的派生类会产生来自不同路径的公共基类的多个拷贝,如果用virtual把公共基类定义成虚基类,则只会保留公共基类的一个拷贝。
典型例题分析与解答例题1:下列对派生类的描述中,()是错误的。
A.一个派生类可以作为另一个派生类的基类B.派生类至少有一个基类C.派生类的成员除了它自己的成员外,还包含了它的基类成员D.派生类中继承的基类成员的访问权限到派生类保持不变答案:D分析:一个派生类可以作为另一个派生类的基类。
5.2基类和派生类
5.2 基类和派生类5.2基类和派生类在C++中,当一种类被其它类继承时,被继承的类称为基类(baseclass)。
继承其它类特性的类称为派生类(derivedclass)。
从本质上看,基类是含有一种类集合中的公共特性,派生类在继承基类特性的同时能够加入自己独有的特性。
基类与派生类之间反映出下述三种不同的现象:(1)派生类是基类的具体化。
即模拟概念层次,表达“is-a”的关系。
(2)派生类是基类的延迟定义。
能够定义一种抽象基类,定义某些操作,使它们服从一定的合同,但许多可能并未实现,然后定义非抽象的派类,实现抽象基类中定义的行为。
这时派生类不是基类的具体化,而是抽象类的实现。
在JAVA中,有专门的纯虚类,称为接口,其作用就是为不同的类提供一种统一的接口,同时间接实现多继承(JAVA不支持多继承)。
(3)派生类是基类的结合。
当一种派生类有多于一种的基类时,它们组合在一起形成含有全部基类行为的类型。
这时要注意,不要用继承体现聚合关系。
5.2.1基类与派生类的阐明先看一种例子。
[例5.1] 派生类的阐明EX5_1.CPP。
继承基类的派生类定义的普通形式:class derived_class_name:access_specifier base_class_name{……};其中access_specifier能够是3个核心字之一:public、private(默认值)或protected。
派生类也称为子类、导出类。
它含有下述特点:(1)可在基类所提供有基础上包含新组员;(2)可在自己类中隐藏基类的任何组员;(3)为新类重新定义基类中的函数;[例5.2] 子类的特点EX5_2.CPP。
5.2.2派生类的继承权与访问域派生类的继承权如果不能有效在加以限制,就不能按照实际状况体现求解问题的复杂性。
因此访问权限是一种很重要的问题。
(1)对于基类的私有组员,派生类及派生类的使用者无权访问。
(2)对于基类的公有组员,则按派生类的定义,分为三种状况:私有派生,继承基类的公有组员作为自己的私有组员,这些组员只能被派生类的组员函数访问。
C++程序设计04737 第5章 类的继承与派生
5.1 类的继承与类的派生
5.1.2 派生类的定义与大小
2.类的大小
1. //[程序5-2]基类与子类占用空间及字节对齐
2. #include <iostream>
3. using namespace std;
4. class BaseClass //基类
5. {
6.
int v1, v2;
7.
派生类中包含了基类的成员变量,且基类
成员变量在前,派生类成员变量在后。基 类占用了12个字节,在此之后要分配派生 类自身的成员变量,一个int型变量和一个 指针变量。在64位系统中,指针占8个字 节。所以派生类的大小=12+4+8=24字节。 32位系统中指针的大小是4字节。
5.1 类的继承与类的派生
5.1 类的继承与类的派生
5.1.3 继承关系的特殊性
//[程序5-3]派生类继承了友元函数
#include <iostream>
using namespace std;
class another;//前向引用声明
class Base//基类
{private: float x;
public: void print(const another &K);};
d.print(ano);//输出: Base: 100
return 0;
}
如果派生类Derived中重写了print(),若还想在函数中访问another的私有成员,则必须将类Derived的print()函数也
声明为another的友元。在类another中需要添加如下声明:
friend void Derived::print(const another &K);//派生类的成员函数声明为本类的友元
派生与继承
继承与派生
(2)改造。改造是指对吸收进来的基类成员的改 改造。 改造 造。它包括两个方面:一个是对基类成员访问 它包括两个方面: 控制的调整, 控制的调整,它是通过派生类定义时的继承方 式来确定。另一个就是对基类成员的隐藏, 式来确定。另一个就是对基类成员的隐藏,即 在派生类中声明一个与基类成员同名的新成员, 在派生类中声明一个与基类成员同名的新成员, 这个新成员就隐藏了上层的所有同名成员。 这个新成员就隐藏了上层的所有同名成员。这 时,在派生类中或者通过派生类的对象来直接 使用该成员名, 使用该成员名,就只能访问到派生类中声明的 同名成员,这称为同名隐藏或同名覆盖。 同名成员,这称为同名隐藏或同名覆盖。
继承与派生
继承性的具体实现也就是一个派生类的建立过程。 继承性的具体实现也就是一个派生类的建立过程。 class 派生类名 : 继承方式 基类名 继承方式 基类名 基类名1, 基类名2, … , 继承方式 基类名 基类名n { 新增派生类成员声明; 新增派生类成员声明 }; 继承方式关键字有三个: 继承方式关键字有三个:public、private、protected。 、 、 。 继承方式关键字只对紧随其后的基类起作用。 继承方式关键字只对紧随其后的基类起作用。 在继承与派生的过程中,一个基类可以派生出多个派生类, 在继承与派生的过程中,一个基类可以派生出多个派生类, 每一个派生类又可以作为基类再派生出新的派生类, 每一个派生类又可以作为基类再派生出新的派生类,基类和 派生类是相对而言的。这样,一代一代地派生下去, 派生类是相对而言的。这样,一代一代地派生下去,就形成 了一个相互关联的有层次的类的家族,称为类族。在类族中, 了一个相互关联的有层次的类的家族,称为类族。在类族中, 作为上下层直接联系而参与派生出某类的基类称为该派生类 的直接基类, 的直接基类,而基类的基类甚至更高层的基类则称为间接基 类。
第4章 派生类与继承
如:
class employee:public person{ char department[20]; float salary; public: //… };
Previous Next Back
5
派生方式
1. 私有派生
class employee:private person{ //… };
//部门 //工资
直接定义employee类,代码重复非常严重。 使用继承:将employee说明成person类的派生类。 增加新的数据成员department和salary; 修改print成员函数。
Previ:
class 派生类名:派生方式 基类名{ //派生类新增的数据成员和成员函数 };
class B{ public: void setB(int x){ b=x; } void showB(){ } private: int b; };
class C : public A, private B{ public: void setC(int x, int y, int z) { //直接访问基类的公有成员 setA(x); setB(y); c=z;} void showC(){ } private: int c; }; void main() { C obj; obj.setA(5); obj.showA( ); obj.setC(6,7,9); obj.showC( ); obj.setB(6); //错误 obj.showB(); //错误 }
公有派生
class employee:public person{ //… }; public
基类
private a fun1() public c fun2() private
第5章 类的派生与继承
第5章 类的派生与继承
class BaseClass //基类 {
int vl,v2; }; class DerivedClass : public BaseClass //派生类 {
int v3; };
第5章 类的派生与继承
二、派生类的定义与大小 1、派生类的定义 从基类派生派生类的一般格式: class派生类名:继承方式说明符 基类名 {
编程小技巧:同学们可以将鼠标放置于类中的任何一个成 员或者函数上,编程软件会提示,对应的访问权限,这个方法在 继承编程中特别好用。
第5章 类的派生与继承
我们几乎不使用 protected 或 private 继承,通常使用 public 继承。当使用不同类型的继承时,遵循以下几个规则: 公有继承(public):当一个类派生自公有基类时,基类的公
第5章 类的派生与继承
C++程序设计
第5章 类的派生和继承
第5章 类的派生与继承
本章内容
类的继承与类的派生 访问控制 派生类的构造函数和析构函数 类之间的关系 多层次派生 基类与派生类指针的相互转换
第5章 类的派生与继承
第一节 类的继承与类的派生
常考知识点: 继承派生基本概念 继承派生在C++中起到的作用 派生类定义的方法 派生类从基类继承的元素有哪些 继承关系中友元和静态成员变量的派生特点 单继承、多重继承的概念以及异同 派生的层次
第5章 类的派生与继承
1、继承:在一个已存在的类的基础上建立一个新的类,称 为继承
2、派生:从已有的类(父类)产生一个新的子类,称为类的 派生
3、单继承:一个派生类只从一个基类派生,这称为单继承 4、多继承:一个派生类有两个或多个基类的称为多重继承
新标准C++程序设计5. 继承和派生
5
需要继承机制的例子
而不同的学生,又有各自不同的属性和方法 研究生 导师 系 大学生 系 中学生 竞赛特长加分
6
需要继承机制的例子
➢如果为每类学生都从头编写一个类,显然会有 不少重复的代码,浪费。
7
需要继承机制的例子
➢如果为每类学生都从头编写一个类,显然会有 不少重复的代码,浪费。
class CPoint {
double x,y; };
class CCircle:public CPoint {
double r; };
31
复合关系的使用
几何形体程序中,需要写“点”类,也需要写“圆”类
class CPoint {
double x,y; };
class CCircle:public CPoint {
class CStudent { private: string name; string id; //学号 char gender; //性别,'F'代表女,'M'代表男 int age; public: void PrintInfo(); void SetInfo( const string & name_,const string & id_, int age_, char gender_ ); string GetName() { return name; }
int v3; };
13
派生类对象的内存空间
派生类对象的体积,等于基类对象的体积,再加上派 生类对象自己的成员变量的体积。在派生类对象中,包 含着基类对象,而且基类对象的存储位置位于派生类对 象新增的成员变量之前。
第八章 继承与派生
一般来说,公有派生是绝对主流。
公有派生与私有派生
1. 公有继承(public)。 公有继承的特点是基类的公有成员和保护成员作为派生 类的成员时,它们都保持原有的状态,而基类的私有成员仍 然是私有的。 2. 私有继承(private)。 私有继承的特点是基类的公有成员和保护成员作为派 生类的私有成员,并且不能被这个派生类的子类访问。
基类 派生类 基类 public public Protected protected private private private 不可见 private 派生 派生类 protected 基类 public protected private 派生类 public proteced
不可见
不可见
在派生类对象外 访问派生类对象 的基类成员
可直接访问 不可直接访问 不可直接访问 不可直接访问 不可直接访问 不可直接访问
公有派生
私有派生
(1)在公有继承时,派生类的对象可以访问基类中的公有成 员;派生类的成员函数可以访问基类中的公有成员和保护成员。 这里,一定要区分清楚派生类的对象和派生类中的成员函数对 基类的访问是不同的。 (2)在私有继承时,基类的成员只能由直接派生类访问,而 无法再往下继承。
继承与派生的概念 派生类的构造函数与析构函数 多重继承与派生类成员标识 虚基类 类层次中成员名的作用域 类层次中类转换规则 多重继承的应用例子 MFC基础类及其层次结构
继承与派生的概念
层次概念是计算机的重要概念。通过继承(inheritance)的 机制可对类(class)分层,提供类型/子类型的关系。C++通过 类派生(class derivation)的机制来支持继承。继承是类之间定 义的一种重要关系。定义类B时,自动得到类A的操作和数据属性, 使得程序员只需定义类A中所没有的新成分就可完成在类B的定义, 这样称类B继承了类A,类A派生了类B,A是基类(父类),B是 派生类(子类)。这种机制称为继承。 称已存在的用来派生新类的类为基类(base class) ,又称 为 父 类 。 由 已 存 在 的 类 派 生 出 的 新 类 称 为 派 生 类 ( derived class) ,又称为子类。派生类可以具有基类的特性,共享基类 的成员函数,使用基类的数据成员,还可以定义自己的新特性, 定义自己的数据成员和成员函数。基类和派生类的集合称作类继 承层次结构(hierarchy) 在C++语言中,一个派生类可以从一个基类派生,也可以从 多个基类派生。从一个基类派生的继承称为单继承;从多个基类 派生的继承称为多继承。下图反映了类之间继承和派生关系。
《C++程序设计》电子教案第5章 继承和派生
// 使用基类成员i,j
// 使用基类成员i,j
4.私有继承和保护继承
私有继承:派生类对基类的私有继承使用关键 字private描述(可缺省),基类的所有公有段 和保护段成员都成为派生类的私有成员。 保护继承:派生类对基类的保护继承使用关键 字protected描述,基类的所有公有段和保护段 成员都成为派生类的保护成员,保护继承在程 序中很少应用。
常用的三种继承方式:
1.公有继承(public) 公有继承的特点是基类的公有成员和保护成员作为派生类 的成员时,它们都保持原有的状态,而基类的私有成员 仍然是私有的。 2.私有继承(private) 私有继承的特点是基类的公有成员和保护成员作为派生类 的私有成员,并且不能被这个派生类的子类访问。 3.保护继承(protected) 保护继承的特点是基类的所有公有成员和保护成员都成为 派生类的保护成员,并且只能被它的派生类成员函数或 友元访问,基类的私有成员仍然是私有的。
第5章 继承和派生
5.1 5.2 5.3 5.4
基类和派生类 单继承 多继承 虚基类
5.1 基类和派生类
5.1.1 5.1.2 5.1.3 5.1.4
派生类的定义格式 派生类的三种继承方式 访问控制 基类和派生类的关系
返回首页
称已存在的用来派生新类的类为基类,又称为 父类。由已存在的类派生出的新类称为派生类, 又称为子类。派生类可以具有基类的特性,共 享基类的成员函数,使用基类的数据成员,还 可以定义自己的新特性,定义自己的数据成员 和成员函数。
public: void initr(float x,float y,float w,float h) { initp(x,y); //调用基类的公有成员 W=w;H=h; } float getH(){return H;} float getW(){return W;} private: float W,H; }; void main() { rectangle rect; rect.initr(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; }
类的具体概念
类的具体概念类是面向对象编程中的一种概念,用于描述具有相似属性和行为的对象的集合。
类是构建对象的蓝图或模板,它定义了对象的属性和方法,并为对象提供了一些通用的行为模式。
在现实世界中,我们可以把类比作是一个工厂,它生产同一类型的产品,每一个具体的产品就是类的实例。
比如说,我们可以创建一个“动物”类,它有属性(如年龄、体重、颜色等)和行为(如吃、睡、行走等)。
然后,我们可以利用这个动物类创建各种具体的动物实例,如狗、猫、鸟等。
类的概念具有以下几个特点:1. 抽象性:类是对一组具有相似特征和行为的对象的抽象描述。
它抓住了这些对象相同的特征和行为,忽略了它们之间的细节差异。
例如,当我们定义一个“车辆”类时,我们不关心具体的车辆是什么样子,只关心它们有轮子、引擎和驾驶的能力。
2. 封装性:类通过将数据和操作封装在一起,提供了一种控制对内部数据和方法的访问的机制。
它隐藏了对象的内部细节,只暴露出一些对外的接口,用于操作对象。
这样一来,对象的使用者只需要知道如何使用这些接口,而不需要关心具体的实现细节。
封装提高了代码的可维护性和可读性,并且降低了代码的耦合性。
3. 继承性:继承是类的一个重要的特性,它允许我们定义一个类,并从已有的类中派生出新的类,从而实现类的层次结构。
被继承的类称为基类或父类,新派生出的类称为子类或派生类。
子类可以继承父类的属性和方法,并且可以重写父类的方法或添加新的属性和方法。
继承提供了代码重用的机制,允许我们构建更加复杂和灵活的系统。
4. 多态性:多态是指在不同的情况下,相同的操作可以以不同的方式被执行。
多态可以通过继承和接口实现,它允许我们使用继承层次中的任意一个类的实例来执行特定的操作,而不需要关心实际的类型。
例如,如果有一个“A动物”类和一个“B动物”类,它们都继承自“动物”类,那么我们可以以相同的方式调用它们的"吃"方法,但是具体的实现会根据不同的动物而有所不同。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
派生类的析构函数 由于析构函数不能继承,因此在派生类的 析构函数中要包含它的直接基类的析构函 数。 派生类析构函数的执行顺序如下: 先执行派生类析构函数的函数体 再执行子对象所在类的析构函数(如果 有子对象的话) 最后执行直接基类中的析构函数。
北京化工大学 VC++ 教学课件
28
计算机系 江志英 jiangzy@
class B:A //默认私有继承 { public: void h() { cout<<"B\n"; } A::f; //引入本作用域 }; void main() { B b; b.f(10); b.g( ); //错 b.h( ); }
北京化工大学 VC++ 教学课件
19
计算机系 江志英 jiangzy@
又称包含关系,一个类中有另一个类中的 对象,表现两者之间的“有”的关系。
北京化工大学 VC++ 教学课件
9
计算机系 江志英 jiangzy@
继承的类型:单继承和多继承
继承可分为: 单重继承,指生成的派生类只有一个基类。 多重继承,是指生成的派生类有两个或两个 以上的基类。
两者的区别仅在于所继承基类数不同
北京化工大学 VC++ 教学课件
10
计算机系 江志英 jiangzy@
派生类的定义
派生类定义格式如下:
class <派生类名>:<继承方式> <基类名> { <派生类新增成员说明> };
北京化工大学 VC++ 教学课件
11
计算机系 江志英 jiangzy@
22
class C:protected B { public: void f4(); protected: int c1; private: int c2; }; class D:private C { public: void f5(); protected: int d1; private: int d2; };
北京化工大学 VC++ 教学课件
计算机系 江志英 jiangzy@
成员类 类A(基类)
f1 f2 f3 a1 a2 () () ()
b
f4 f5 c1 c2 d1 d2 () () × × × × × × × × 私 × × × 有 公 保 私 有 护 有
公 保 私 × × × × × 有 护 有 不 公 保 公 保 私 类B(公继) 可 × × 有 护 有 护 有 访 公 保 类C(保继) 有 护
北京化工大学 VC++ 教学课件
13
计算机系 江志英 jiangzy@
基类成员在派生类中访问权限
基类中成员 私成员 公成员 保护成员
公有继承 不可访问 公有 保护
私有继承 不可访问 私有 私有
保护继承 不可访问 保护 保护
基类私有不可访问,公有不变,私有私有,保护保护。
先执行基类构造函数; 再执行子对象的构造函数(如有子对象的话); 最后执行派生类构造函数的函数体。
② 派生类构造函数的成员初始化列表中应该显
式地包含基类中带参数的构造函数,或者隐含地 包含基类中的默认构造函数。
北京化工大学 VC++ 教学课件
27
计算机系 江志英 jiangzy@
继承与派生的目的
继承的目的: 实现代码重用 派生的目的: 当新的问题出现,原有程序无法解决(或不能 完全解决)时,需要对原有程序进行改造。
北京化工大学 VC++ 教学课件
8
计算机系 江志英 jiangzy@
类与类之间的关系
继承关系:
描述了派生类与基类之间的“是”关系, 派生类是基类中的一种,是它的具体化。 组合关系:
北京化工大学 VC++ 教学课件
14
计算机系 江志英 jiangzy@
成员访问权限的控制 (1) 公有继承方式
class Point //基类Point类的声明 { public: //公有函数成员 void InitP(float xx=0, float yy=0) {X=xx;Y=yy;} void Move(float xOff, float yOff) {X+=xOff;Y+=yOff;} float GetX() {return X;} float GetY() {return Y;} private: //私有数据成员 float X,Y; };
北京化工大学 VC++ 教学课件
21
计算机系 江志英 jiangzy@
例 分析下列程序,并填写不同成员在不同类的访问权限。
#include <iostream.h> class A { public: void f1(); protected: int a1; private: int a2; }; class B:public A { public: void f2(); protected: void f3(); private: int b; };
5
计算机系 江志英 jiangzy@
几何形状
圆
矩形
北京化工大学 VC++ 教学课件
6
计算机系 江志英 jiangzy@
雇员
兼职技术人员
管理人员
销售人员
销售经理
北京化工大学 VC++ 教学课件
7
计算机系 江志英 jiangzy@
例 派生类构造函数的执行顺序 #include <iostream.h> class A { public: A( ) { a=0; cout<<"Default constructor called."<<a<<endl; } A(int i) { a=i; cout<<"Constructor called."<<a<<endl; } ~A( ) { cout<<"Destructor called."<<a<<endl; } void Print( ) { cout<<a<<','; } int Geta( ) { return a; } private: int a; };
class B:public A { public: void f2(); protected: int j2; private: int i2; };
北京化工大学 VC++ 教学课件 例2
18
计算机系 江志英 jiangzy@
(2)私有继承方式
#include <iostream.h> class A { public: void f(int i) { cout<<i<<endl; } void g() { cout<<"A\n"; } };
<派生类构造函数名> (<总参数表>):<基类构造函数名>
(<参数表>),<其他初始化项> { <派生类自身数据成员初始化> }
北京化工大学 VC++ 教学课件
26
计算机系 江志英 jiangzy@
掌握派生类构造函数时应注意如下两点
① 派生类构造函数的执行顺序如下:
派生类的构造函数承担着对基类中数据成员 初始化和对派生类自身数据成员初始化的双重 任务。
析构函数不能继承。
派生类的析构函数应包含着基类的析构函数, 用来释放基类中的数据成员。
北京化工大学 VC++ 教学课件
25
计算机系 江志英 jiangzy@
派生类的构造函数 •派生类的构造函数应该包含它的直接基类的 构造函数。定义格式如下:
类D(私继)
北京化工大学 VC++ 教学课件
23
计算机系 江志英 jiangzy@
2 单继承 单重继承指的是仅有一个基类的派生继承。
动物
猴子
猫
鸟
狮子
虎
猎豹
北京化工大学 VC++ 教学课件
24
计算机系 江志英 jiangzy@
派生类的构造函数和析构函数 构造函数不能继承。
北京化工大学 VC++ 教学课件
3
计算机系 江志英 jiangzy@
交通工具
汽车
小汽车
卡车
旅行车
工具车
面包车
轿车
北京化工大学 VC++ 教学课件
4
计算机系 江志英 jiangzy@
动物
猴子
猫
鸟
老虎
豹
狮子
北京化工大学 VC++ 教学课件
派生类的三种继承方式
不同继承方式的影响主要体现在 派生类成员对基类成员的访问权限 通过派生类对象对基类成员的访问权限 继承方式包含以下3种:
public(公有的方式);
private(私有的方式); protected(保护的方式)。 默认方式: 对class来讲是private; 对struct来讲是public。
北京化工大学 VC++ 教学课件 例1
15
计算机系 江志英 jiangzy@
class Rectangle: //新增公有函数成员 void InitR(float x, float y, float w, float h) {InitP(x,y);W=w;H=h;}//调用基类公有成员函数 float GetH() {return H;} float GetW() {return W;} private: //新增私有数据成员 float W,H; };