第7章 继承性和派生类

合集下载

C语言程序设计 继承性和派生类

C语言程序设计  继承性和派生类
protected: int j1;
private: int i1;
};
class B:public A {
public: void f2();
protected : int j2;
private: int i2;
}; class C:public B
{ public: void f3();
};
第七章
f1( ),j1和i1吗? 答: 可以访问直接基类中的f2( )和j2以及间接基类 中的f1( )和j1,而不可以访问 i2和i1 。
第七章
4、派生类C的对象c1能否访问直接基类B中的成员: f2( ),i2和j2吗?能否访问间接基类A中的成员: f1( ),j1和i1吗?
答: 可以访问直接基类中的f2( )和间接基类中的f1( ),其 他的都不可访问。
基类成员由于继承方式的不同在派生类中的访问
权限不同,三种不同的继承方式的基类特性与派生类
特性如表:
继承方式 公有继承 私有继承
保护继承
基类特性
public protected private public protected private
public protected private
派生类特性
public protected 不可访问 private private 不可访问
注意:基类和派生类是相对而言的。一个基类可 以是另一个基类的派生类,这样便形成了复杂的继承
第七章
结构,出现了类的层次。一个基类派生出一个派生类, 该派生类做另一个派生类的基类,则该派生类称为原 来基类的直接派生类,而原来基类为另一个派生类的 间接基类。
第二节 基类成员在派生类中 的访问权限
第七章

C语言程序设计PPT第七章继承与派生

C语言程序设计PPT第七章继承与派生
cout<<"C's constructor called."<<endl; } C::~C() { cout<<"C's destructor called."<<endl; } void C::Print() const { B::Print(); cout<<c<<endl; } int main() { C obj(5,6); obj.Print(); }
问 控 制
类中的public和protected成员,但 不能直接访问基类的private成员。
通过派生类的对象不能直接访问基类 中的任何成员
17
C++语言程序设计
protected 成员的特点与作用

成 对建立其所在类对象的模块来说,它
员 与 private 成员的性质相同。
的 对于其派生类来说,它与 public 成 访 员的性质相同。
public成员。
10
C++语言程序设计
例7-1 公有继承举例
类 成 员
class Point //基类Point类的声明 {public: //公有函数成员
void InitP(float xx=0, float yy=0)

{X=xx;Y=yy;}
访 void Move(float xOff, float yOff)
25
C++语言程序设计
多继承时派生类的声明

继 class 派生类名:继承方式1 基类名1,
承 继承方式2 基类名2,...
与{

成员声明;

《继承与派生 》课件

《继承与派生 》课件
《继承与派生》PPT 课件
目录
CONTENTS
• 继承与派生的基本概念 • 继承的方式 • 派生类的构造函数和析构函数 • 继承与多态 • 继承与重载
01
继承与派生的基本 概念
继承的定义
继承是面向对象编程中的一个重 要概念,它允许一个类(子类) 继承另一个类(父类)的属性和
方法。
通过继承,子类可以复用父类的 代码,减少代码冗余,提高代码
保护继承
总结词
保护继承是指基类的保护成员在派生类 中保持保护属性,可以被派生类和派生 类的对象访问。
VS
详细描述
保护继承时,基类的保护成员在派生类中 保持保护属性,可以被派生类和派生类的 对象访问。这种继承方式使得基类的保护 成员成为派生类的保护成员,可以被派生 类和派生类的对象访问。因此,派生类可 以继承基类的保护成员函数和变量。
03
派生类的构造函数 和析构函数
派生类的构造函数
派生类构造函数的作用
派生类构造函数用于初始化派生类对象,包括调用基类构造函数 和执行派生类特有的初始化操作。
派生类构造函数的执行顺序
派生类构造函数的执行顺序是在创建派生类对象时,先调用基类构 造函数,然后执行派生类构造函数体中的代码。
派生类构造函数的参数
继承和派生共同实现 了面向对象编程中的 代码复用和多态性。
派生是继承的一种表 现形式,通过派生可 以创建新的类。
02
继承的方式
公有继承
总结词
公有继承是ቤተ መጻሕፍቲ ባይዱ基类的公有成员在派生类中仍为公有成员,可以被派生类和派生类的对象访问。
详细描述
公有继承时,基类的公有成员在派生类中保持公有属性,派生类可以访问基类的公有和保护成员。这种继承方式 使得基类的公有成员成为派生类的公有成员,可以被派生类和派生类的对象直接访问,因此派生类可以继承基类 的公有成员函数和变量。

软件工程导论(第7章)

软件工程导论(第7章)

测试的正确定义:“为了发现程序中的错 误而执行程序的过程。”
7.2.2 软件测试准则
1)所有测试都应该能追溯到用户需求;
2)应该远在测试前就制定出测试计划;
3)把Pareto原理应用到软件测试中;Pareto原理 说明测试发现的错误中的80%很可能是由程序 中20%的模块造成的。
4)应该从“小规模”测试开始,并逐步进行“大 规模”测试;
USER32.DLL; GDI32.DLL; KERNEL32.DLL。
Windows消息机制:
1)基于消息的事件驱动 消息可以是由硬件发来的(存于系统队列),
也可以由Windows系统和应用程序发来(存于 程序队列中);
每一个Windows程序在不停的捕捉各种消息, 并进行处理;
每个窗口都必须有一个窗口函数,来负责消息 的判断与处理。
3)重要的执行路径 由于不可能进行穷尽测试,因此选择测试
路径是非常关键的。 4)出错处理通路 5)边界条件
7.3.2 代码审查
审查小组: 1)组长; 2)程序的设计者; 3)程序的编写者; 4)程序的测试者。
7.3.3 计算机测试
由于软件模块不是一个独立的系统,不能独 立运行,要依靠其他模块调用,或需要调用其 他模块。
1.模块测试 模块测试又称单元测试,它把每个模块作为
单独的实体来测试。 2.子系统测试
子系统测试是把经过单元测试的模块放在一 起形成一个子系统来测试。
3.系统测试 系统测试是把经过测试的子系统装配成一个完
整的系统来测试。 4.验收测试
验收测试把软件系统作为单一的实体进行测试 (利用用户的实际数据测试)。 5.平行运行
如PL/1、PASCAL、C、ADA等 3)专用语言 如APL、BLISS、FORTH、LISP、PROLOG等

第七章 继承性与派生类

第七章 继承性与派生类
1.2 派生类的三种继承方式
l 公有继承(public) 基类的公有成员和保护成员作为派生类的成员时,它们都 保持原有的状态,而基类的私有成员仍然是有的
l 私有继承(private) 基类的公有成员和保护成员都作为派生类的私有成员,并 且不能被这个派生类的子类所访问
l 保护继承(protected) 基类的所有公有成员和保护成员都作为派生类的保护成员, 并且只能被它的派生类成员函数或友元访问,基类的私有 成员仍然是私有的
保护继承方式创建的派生类对基类各种成 员访问权限如下 :
– 基类的公有成员和保护成员都相当于派生 类的保护成员,派生类可以通过自身的成 员函数或其子类的成员函数访问他们
– 对于基类的私有成员,无论派生类内部成 员或派生类使用者都无法直接访问
[例] 分析程序,回答问题
Include <iostream.h> #include <string.h> class A {
public: A(const char *nm){strcpy(name, nm);}
private: char name[80];
}; class B::public A {
public: B(const char *nm):A(nm); {} void PrintName( )const;
};
l 系统的默认值是私有继承(private)。
不同继承方式的基类和派生类特性
类成员 对象 public 对象 protected 对象 private 对象
类型
继承类
继承类
继承类
priv X
X
X
X
X
X
X
prote X prote X

第七章 继承选择题

第七章 继承选择题

1、下列对基类和派生类关系的描述中,错误的是_________。

A)派生类是基类的具体化B)派生类是基类的子集C)派生类是基类定义的延续D)派生类是基类的组合2、继承具有_________ ,即当基类本身也是某一个类的派生类时,底层的派生类也会自动继承间接基类的成员。

A)规律性B)传递性C)重复性D)多样性3、下面_________的叙述不符合赋值兼容规则。

A)派生类的对象可以赋值给基类的对象B)基类的对象可以赋值给派生类的对象C)派生类的对象可以初始化基类的引用D)派生类的对象的地址可以赋值给指向基类的指针5、下面叙述错误的是_________。

A)派生类可以使用private派生B)对基类成员的访问必须是无二义性的C)基类成员的访问能力在派生类中维持不变D)赋值兼容规则也适用于多继承的组合6、下列说法中错误的是_________。

A)公有继承时基类中的public成员在派生类中仍是public的B)公有继承时基类中的private成员在派生类中仍是private的C)私有继承时基类中的public成员在派生类中是private的D)保护继承时基类中的public成员在派生类中是protected的7、C++的类有两种用法:一种是类的实例化,即生成类的对象,并参与系统的运行;另一种是通过_________派生出新的类。

A)复用B)继承C)封装D)引用8、下列关于虚基类的描述中,错误的是_________。

A)虚基类子对象的初始化由最派生类完成B)虚基类子对象的初始化次数与虚基类下面的派生类个数有关C)设置虚基类的目的是消除二义性D)带有虚基类的多层派生类构造函数的成员初始化列表中都要列出对虚基类构造函数的调用9、派生类的构造函数的成员初始化列表中,不能包含_________。

A)基类的构造函数B)派生类中子对象的初始化C)基类中子对象的初始化D)派生类中一般数据成员的初始化10、C++类体系中,不能被派生类继承的有_________。

《继承和派生》课件

《继承和派生》课件
时提供默认值。
派生类的析构函数
派生类析构函数在销毁派生类对象时 自动调用,用于释放派生类所占用的 资源。
派生类析构函数可以包含代码,用于 清理派生类所占用的资源。
派生类析构函数可以访问基类的析构 函数,通过使用`this`关键字调用基类 析构函数。
派生类析构函数可以重载基类析构函 数,以便在销毁派生类对象时执行特 定的操作。
基类析构函数的调用
在派生类的析构函数中,可以通过使用`this`关键字调 用基类的析构函数,以确保基类资源得到正确释放。
输标02入题
如果在派生类的析构函数中没有显式调用基类的析构 函数,则编译器会自动调用基类的默认析构函数。
01
03
在某些情况下,可能需要显式调用基类的析构函数, 以确保资源得到正确释放。例如,当基类包含动态分
02 继承的方式
公有继承
总结词
公有继承是指子类可以访问父类的公有成员。
详细描述
在公有继承中,子类可以访问父类的公有成员(即不加任 何修饰符的成员),这些成员在子类中保持公有属性。子 类可以继承和使用父类的公有成员,包括函数、变量、常 量等。
总结词
公有继承是实现代码复用的一种方式。
详细描述
通过公有继承,子类可以继承父类的公有成员,从而避免 重复编写相同的代码。这有助于提高代码的复用性和维护 性。
注意事项
虚函数和纯虚函数的使用 应合理规划,避免过度使 用导致程序复杂度和维护 成本增加。
继承和派生的效率问题
继承
通过共享已存在的代码, 减少代码冗余。但也可能 导致内存浪费和性能下降 。
派生
通过扩展已有类,增加新 功能或修改已有功能。但 也可能导致内存消耗增加 和性能下降。
注意事项

C++ 第7章 继承与派生

C++ 第7章   继承与派生

【 7.1 公司雇员档案的管理】
程序执行后的显示结果如下: zhang: 23 : 610.5 zhao: 27 : 824.75 li: 32 : 812.45 level:11 cui: 34 : 1200.5manageremployengineerdirector meng: 26 : 1420.1 speciality:E academic degree:M zhou: 38 : 1800.2 level:2 post:1
7.2 派生类说明及其构造和析构函数 【 7.2.2 有关成员存取权限问题的进一步讨论】
下面给出一个程序,请仔细分析其中的类继承与派生关系, 找出所有违反存取权限的使用情况(语句)
#include <iostream.h> class B {
int priDat;
protected: int proDat;
7.2 派生类说明及其构造和析构函数 【 7.2.1 派生类说明】
派生类说明的一般格式:
列出所给类的基类 每个基类说明格式为: <派生方式><基类名>
class<类名>:<基类说明表> { private: 派生方式:公有派生,保护派生或私有派生。 <私有成员表> Public 表示公有派生, protected: protected 表示保护派生, <保护成员表> private 表示私有派生。 public: 派生方式决定了从基类继承过来的成员在派生 类中的封装属性。 <公有成员表> };
第七章 继承与派生
计算机类
台式机类
便携式类
a) 单继承 输入设备类 输出设备类
硬盘类 b) 多继承 图 单继承与多继承

c++7继承与派生

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++语言程序设计 第七章 继承性和派生类

C++语言程序设计 第七章 继承性和派生类

第七章 } 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(); }
执行该程序输出结果如下 :
A's default constructor called. A's default constructor called. B's default constructor called. A's default constructor called. A's default constructor called. B's default constructor called.
class<派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2> class<派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>… 派生类名>:<继承方式 基类名1>,<继承方式 基类名2> {
< 派生类新定义成员 >
};
第七章
五、基类与派生类的关系: 基类与派生类的关系:
第七章
继承性和派生类
第七章
继承性是面向对象程序设计中重要机制之一 继承性是面向对象程序设计中重要机制之一。这 之一 种机制改变了过去传统的非面向对象程序设计中那种 对不再适合要求的用户定义数据类型进行改写甚至重 写的方法,克服了传统程序设计方法对编写出来的程序 克服了传统程序设计方法对编写出来的程序 无法重复使用而造成资源的浪费的缺点。 无法重复使用而造成资源的浪费的缺点。面向对象程 序设计的继承机制给我们提供了无限重复利用程序资 继承机制给我们提供了无限重复利用程序资 源的一种途径。 源的一种途径。通过C++语言中的继承机制,可以扩充 和完善旧的程序设计以适应新的需求,这样不仅可以节 省程序开发的时间和资源,并且为未来程序设计增添了 新的资源。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第7章继承性和派生类本章内容:基类和派生类、单继承、多继承、虚基类。

类面向对象系统三要素对象继承封装性基础面向对象系统三特征继承性关键多态性补充继承是面向对象程序设计中软件重用的关键技术。

继承机制使用已经定义的类作为基础建立新的类定义,新的类是原有类的数据﹑操作和新类所增加的数据﹑操作的组合。

新的类把原有类作为基类引用,而不需要修改原有类的定义。

新定义的类作为派生类引用。

这种可扩充﹑可重用技术大大降低了大型软件的开发难度和维护费用。

7.1 基类和派生类我们称已存在的用来派生新类的类为基类,又称为父类。

由已存在的类派生出的新类称为派生类,又称为子类。

在C++语言中,一个派生类可以从一个基类派生,也可以从多个基类派生。

从一个基类派生的继承称为单继承;从多个基类派生的继承称为多继承。

单继承 多继承 7.1.1派生类的定义格式 单继承的定义格式:class 派生类名:继承方式 基类名 {派生类新定义成员 };public 表示公有继承 继承方式 private 表示私有继承protected 表示保护继承继承方式规定了如何访问从基类继承的成员。

继承方式却省,隐含私有继承。

多继承的定义格式如下:class 派生类名:继承方式1 基类名1,继承方式2 基类名2,…{派生类新定义成员};7.1.2 派生类的三种继承方式1.公有继承(public)公有成员是类的接口,在类中和类外可见。

特点:基类的公有和保护成员的访问属性在派生类中不变、而基类的私有成员不可访问。

基类成员派生类新定义成员成员派生类的对象可以访问基类中的公有成员;派生类的成员函数可以访问基类中的公有成员和保护成员。

2.私有继承(private)私有成员只能在类中可见,不能再类外或派生类中使用。

特点:基类中的公有成员和保护成员都以私有成员身份出现在派生类中,而基类的私有成员在派生类中不可访问。

基类成员派生类新定义成员成员派生类的成员函数可以访问基类中的公有成员和保护成员。

而无法再往下继承。

3.保护继承(protected)保护成员在类中和它的派生类中可见。

特点:基类的公有和保护成员都以保护成员的身份出现在派生类中,并且只能被它的派生类成员函数或友元函数访问,而基类的私有成员不可访问。

基类成员 派生类 新定义成员 成员派生类的成员函数可以访问基类中的公有成员和保护成员。

三种不同的继承方式的基类和派生类特性。

7.1.3 基类与派生类的关系在这个层次结构中,由上到下,是一个具体化、特殊化的过程;由下到上,是一个抽象化的过程。

最高层抽象程度最高,从上到下加入了自己的新特征,而最下层是最为具体的。

在派生过程中,派生出来的新类也同样可以作为基类再继续派生新的类。

直接参与派生出某类的基类称为直接基类。

基类的基类称为间接基类,比如A类派生出B类,B类又派生出C类。

则B类是C类的直接基类,A 类是B类的直接基类。

而A类可以称为C类的间接基类。

7.2 单继承7.2.1 成员访问权限的控制例7.1#include<iostream.h>class A{ public:void f1( );protected:int j1;private:int i1;};class B:public A{ public:void f2( );protected:int j2;private:int i2;};class C:public B{ public:void f3( );};问题:1.派生类B中f2( )能否访问基类A中:f1( ),j1,i1?2.派生类B中b1能否访问基类A中:f1( ),j1,i1?3.派生类C中f3( )能否访问直接基类B中:f2( ),j2,i2?能否访问间接基类A中:f1( ),j1,i1?4.派生类C中对象c3能否访问直接基类B中:f2( ), j2,i2?能否访问间接基类A中:f1( ),j1,i1?例 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”;}A::f;};void main( ){ B d1;d1.f(6);d1.g( );d1.h( );}问题:1.d1.g( );出现编译错。

2.去掉d1.g( );执行结果为:6h3. A::f;将基类中的公有成员说明成派生类的公有成员。

4.将私有继承改为公有继承输出为:6gh例 7.3#include<iostream.h>#include<string.h>class A{ public:A(const char *nm){ strcpy(name,nm);}private:char name[80];};class B:public A{ public:B(const char *nm):A(nm){ }void PrintName( ) const{ cout<<”name:”<<name<<endl;} };void main( ){ B b1(“wang li”);b1.PrintName( );}问题:1.cout<<”name:”<<name<<endl;编译错。

2.将类A中private改为protected。

3.输出为:name:wang li7.2.2派生类的构造和析构函数派生类继承了基类的成员,实现了原有代码的重用,这只是一部分,而代码的扩充才是最主要的,只有通过添加新的成员,加入新的功能,类的派生才有实际意义。

基类的构造函数和析构函数不能被继承。

在派生类中,如果对派生类新增的成员进行初始化,就必须由程序员针对实际需要加入新的构造函数。

与此同时,对所有从基类继承下来的成员的初始化工作,还是由基类的构造函数完成,我们必须在派生类中对基类的构造函数所需要的参数进行设置。

1.构造函数派生类构造函数的一般形式为:派生类名(派生类构造函数总叁数表):基类构造函数(参数表1),子对象名(参数表2){ 派生类中数据成员初始化}派生类构造函数执行的一般次序如下:1.基类构造函数。

2.子对象的构造函数。

3.派生类构造函数下面分别举例子说明各个不同的继承方式:例 7.4 公有继承#include<iostream.h>class Point //基类Point { public:Point(float xx=0,float yy=0){X=xx;Y=yy;}void Move(float x,float y){X+=x;Y+=y;}void print1( ){cout<<X<<”,”<<Y<<endl;}private:float X,Y;};class Rectangle: public Point //派生类{public: //新增公有成员Rectangle(float x,float y,float w,float h ) :Point(x,y){W=w;H=h;}void print2( ){cout<<W<<”,”<<H<<endl;}private: //新增私有数据成员float W,H;};void main( ){ Rectangle rect(2,3,20,10); //定义对象rect.Move(3,2); //移动点位置cout<<"The data of rect(X,Y,W,H):"<<endl; rect.print1( );//输出点参数rect.print2( );//输出矩形参数}输出:The data of rect(X,Y,W,H):5,520,10例 7.5 保护继承#include<iostream.h>class Point //基类Point { public:Point(float xx=0,float yy=0) {X=xx;Y=yy;} v oid Move(float x,float y) {X+=x;Y+=y;}void print1( ){cout<<X<<","<<Y<<endl;}private:float X,Y;};class Rectangle: protected Point //派生类{public: //新增公有成员Rectangle(float x,float y,float w,float h ) :Point(x,y){W=w;H=h;}Point::Move;Point::print1;void print2( ){cout<<W<<","<<H<<endl;}private: //新增私有数据成员f loat W,H;};void main(){ Rectangle rect(2,3,20,10); //定义对象rect.Move(3,2); //移动点位置cout<<"The data of rect(X,Y,W,H):"<<endl; rect.print1( );//输出点参数rect.print2( );//输出矩形参数}例7.6私有继承#include<iostream.h>class Point //基类{public:Point(float xx=0, float yy=0){X=xx;Y=yy;}void Move(float xOff, float yOff){X+=xOff;Y+=yOff;}void print( ){cout<<X<<","<<Y<<endl;}private:float X,Y;};class Rectangle: private Point //派生类{public: //新增公有成员Rectangle(float x, float y, float w, float h) :Point(x,y){W=w;H=h;}void Move(float xOff, float yOff){Point::Move(xOff,yOff);}void print( ){Point::print( );cout<<W<<","<<H<<endl;}private: //新增私有数据float W,H;};void main( ){ Rectangle rect(2,3,20,10); //定义对象rect.Move(3,2); //移动点位置cout<<"The data of rect(X,Y,W,H):"<<endl;rect.print( );}输出:The data of rect(X,Y,W,H):5,520,10和例7.4主函数最大的不同是:本例的Rectangle 类对象rect调用的函数都是派生类自身的公有成员,因为是私有继承,它不可能访问到任何一个基类的成员。

相关文档
最新文档