第8章动物类派生继承与多态
派生继承多态详解

16:02
面向对象程序设计(C++描述)
成信院 李代伟
#include <iostream> #include <cmath> using namecpace std; int main( ) { //通过派生类对象只能访问本类成员 通过派生类对象只能访问本类成员 Rectangle rect; rect.InitR(2, 3, 20, 10); rect.Move(3, 2); cout << rect.GetX( ) << ',' << rect.GetY( ) << ',' << rect.GetH( ) << ',' << rect.GetW( ) << endl; return 0; }
成信院 李代伟
公有继承(public) 公有继承 类 成 员 的 访 问 控 制
基类的public和protected成员的访问 和 基类的 成员的访问 属性在派生类中保持不变 保持不变, 属性在派生类中保持不变,但基类的 private成员不可直接访问。 成员不可直接访问 成员不可直接访问。 派生类中的成员函数可以直接访问基类 中的public和protected成员,但不能 成员, 中的 和 成员 直接访问基类的private成员。 成员。 直接访问基类的 成员 通过派生类的对象只能访问基类的 public成员。 成员。 成员
不同继承方式的影响主要体现在: 不同继承方式的影响主要体现在:
派生类成员对基类成员的访问权限 派生类成员对基类成员的访问权限 成员 通过派生类对象 对象对基类成员的访问权限 通过派生类对象对基类成员的访问权限
第8章动物类派生——继承与多态

/
例8-3部分代码:
class Mammal {... } //哺乳动物类 class Horse : Mammal {... } //马类 class Whale : Mammal {... } //鲸鱼类 Program类的Main方法部分语句: Horse aHorse = new Horse("乌骓马"); Mammal aMammal = aHorse; aMammal = new Mammal("老虎A"); aHorse = aMammal as Horse; //哺乳动物老虎A当作马?不行,值null if (aMammal is Horse) //哺乳动物老虎A是马吗?( false) { aHorse = (Horse)aMammal; ... } Whale aWhale = new Whale("鲸鱼A"); //aHorse = aWhale; //编译出错,鲸鱼不是马
8.1 项目预览 8.2 继承与派生 8.3 派生类调用基类的构造函数 8.4 类声明的变量赋值 8.5 用new新建派生类成员以隐藏并替换基类同名成员 8.6 派生类用override重写基类virtual成员 8.7 多态性 8.8 用protected声明被派生类继承的受保护成员 8.9 理解扩展方法 8.10 本章小结 8.11 项目实训8:动物类派生马和鲸鱼、人类派生学生
/
8.7 多态性
一个类通过派生或实现接口可演化 成多种类型,这就是类的多态性。 基类的虚拟方法被不同的派生类重 写,致使调用同一个基类方法,在 运行时实际上能调用不同派生类的 方法,因而产生不同的结果。 同一方法调用形式能调用不同版本 的方法,就属于多态性。 被调用的派生类方法(或属性), 是运行时动态确定的。 【例8-6】在例8-5建立的控制台应 用程序项目中,编写代码,测试类 的多态性。
《继承与派生 》课件

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

习题八第八章继承与派生1.下列对派生类的描述中,(D.派生类中继承的基类成员的访问权限到派生类保持不变)是错误的。
A.一个派生类可以作为另一个派生类的基类B.派生类至少有一个基类C.派生类的成员除了它自己的成员外,还包含了它的基类成员D.派生类中继承的基类成员的访问权限到派生类保持不变2. 派生类的对象对它的哪一类基类成员是可以访问的?(A.公有继承的基类的公有成员)A.公有继承的基类的公有成员 B. 公有继承的基类的保护成员C. 公有继承的基类的私有成员D. 保护继承的基类的公有成员3. 关于多继承二义性的描述,(D.派生类和它的基类中出现同名函数时,将可能出现二义性)是错误的。
A.派生类的多个基类中存在同名成员时,派生类对这个成员访问可能出现二义性B.一个派生类是从具有共同的间接基类的两个基类派生来的,派生类对该公共基类的访问可能出现二义性C.解决二义性最常用的方法是作用域运算符对成员进行限定D.派生类和它的基类中出现同名函数时,将可能出现二义性4. 多继承派生类构造函数构造对象时,(B.虚基类的构造函数)被最先调用。
A.派生类自己的构造函数B.虚基类的构造函数C.非虚基类的构造函数 D.派生类中子对象类的构造函数5. C++类体系中,能被派生类继承的是( B.虚函数)。
A.构造函数 B.虚函数 C.析构函数 D.友元函数6. 设有基类定义:class Cbase{ private: int a;protected: int b;public: int c;};派生类采用何种继承方式可以使成员变量b成为自己的私有成员(A. 私有继承)A. 私有继承B.保护继承C. 公有继承D.私有、保护、公有均可7. 指出下列对定义重载函数的要求中,哪些是错误的提法。
A.要求参数的个数不同B. 要求参数中至少有一个类型不同。
A.要求参数的个数不同。
B.要求参数中至少有一个类型不同。
C.不要求函数的返回值不同。
%AB%98级语言C++程序设计(第一版)-第八章

202第八章继承与派生(Inheritance and Derive)第八章 继承与派生(Inheritance and Derive) C++程序用不同的类定义来表示一组数据及对这些数据的操作,往往在不同的类之间有某种关系,除了上一章介绍的包含关系和友元关系之外,更多的是继承与派生关系。
例如,一个公司或工厂的计算机管理系统,与设备有关的数据,如设备登号、设备购入时间、设备价值等数据及若干操作的可以构成一个类。
交通工具是设备中的一类,它除了作为设备具有一般性之外,又会有一些作为交通工具的特定数据及操作,如它应有由公安机关发给的牌照号等。
又如汽车,它是交通工具的一种。
司机姓名、牌号,可能是它特有的数据。
而货车、轿车、大客车又是汽车中的不同集合,与它们分别相关的又会有不少数据,如轿车的使用人姓名、货车的吨位、客车的载人数等等,都是它们特有的数据项。
把与设备,交通工具,汽车,轿车,货车,客车相关的数据及操作定义为互不相关的独立的类是不科学的,同时,也会造成许多重复内容,例如,所有这些类,都包括同一个数据成员:设备登记号、购入时间等等。
不同类的定义应反映出类之间的相关关系,反映出上面例子中的层次关系。
C++语言中提供了类定义的派生和继承的功能,很好地解决了上面提出的问题。
两个类之间的继承关系,若类A是类B的基类,则类B是类A的派生类。
我们首先从下面的实例中学习如何建立类与类之间的继承关系。
8.1 公司雇员档案的管理 公司中的雇员档案的管理是整个公司的管理系统的一个组成部分,其雇员的档案数据内容一般根据雇员在公司中的不同职责和位置而有所区别。
除了一般雇员之外,可能还有管理人员、工程技术人员和高级主管,这些人员也是雇8.1 公司雇员档案的管理203员,但他们又有其特殊性,在数据库中又必须保存某些特定的信息,例如管理人员有级别信息,技术人员有学位、专业信息等等。
因此,在管理软件中所设计的类应反映其层次关系和特殊性,下面的程序是一个简化了的层次模块结构。
《继承性和派生性》PPT课件

继承方式: public private
protected 直接继承
(P)
6
8.1.2 派生类的三种继承方式(续)
表:继承对基类成员的访问能力
公有继承 私有继承 保护继承
J PHV J PHV J PHV
私有 成员
公有 成员
√√√√√√ (私)
√√ (保)
√
保护 成员
√
√
√
(私)
√
√
精选课件ppt
<派生类新定义成员> };
2、多继承
class <派生类名>:<继承方式1> <基类名1>, <继承方式2> <基类名2>...
{ <派生类新定义成员>
};
精选课件ppt
3
8.1.1 派生类的定义格式(续)
3、继承方式 public:公有继承;
private:私有继承;
protected:保护继承; 作用:控制基类中声明的成员在多大的范围内 能被派生类的用户访问;
7
8.1.2 派生类的三种继承方式(续)
说明: 私有成员不参与继承的访问控制;
基类实例(J):与继承方式无关,遵循访问控制 权限的定义;
直接继承(P):可以访问基类中的公有成员和 保护成员,但成员的权限随继承方式而改变;
水平访问(H)=P+J;
垂直访问(V)=P+P;
保护成员:在垂直访问(V)时相当于公有成员, 在水平访问(H)时相当于私有成员;
14
8.1.2 派生类的三种继承方式(续)
{ Location::Move(xOff,yOff); }
int GetX() {return Location::GetX();}
第八章 继承与多态习题(C++)

第八章继承与多态习题一.基本概念与基础知识自测题8.1填空题8.1.1 如果类α继承了类β,则类α称为(1)类,而类β称为(2)类。
(3)类的对象可作为(4)类的对象处理,反过来不行,因为(5)。
如果强制转换则要注意(6)。
答案:(1)基类(2)派生类(3)派生类(4)基类(5)派生类有一些新成员(6)只能派生类强制转换为基类8.1.2 当用public继承从基类派生一个类时,基类的public成员成为派生类的(1)成员,protected成员成为派生类的(2)成员,对private成员是(3)。
公有派生可以使其类的(4),所以公有派生是主流。
答案:(1)public成员(2)protected成员(3)不可访问(4)接口不变8.1.3 利用继承能够实现(1)。
这种实现缩短了程序开发的时间,VC++中的(2)很好地体现了这一点。
答案:(1)代码的复用(2)MFC编程8.1.4 一个派生类只有一个直接基类的情况称为(1),而有多个直接基类的情况称为(2)。
继承体现了类的(3)概念,这在MFC中得到了很好表现,MFC中只采用了(4)。
答案:(1)单继承(2)多重继承(3)层次(4)单继承8.1.5 C++中多态性包括两种多态性:(1)和(2)。
前者是通过(3)实现的,而后者是通过(4)和(5)来实现的。
答案:(1)编译时的(2)运行时的(3)函数和运算符的重载(4)类继承关系(5)虚函数8.1.6 在基类中将一个成员函数说明成虚函数后,在其派生类中只要(1)、(2)和(3)完全一样就认为是虚函数,而不必再加关键字(4)。
如有任何不同,则认为是(5)而不是虚函数。
除了非成员函数不能作为虚函数外,(6)、(7)和(8)也不能作为虚函数。
答案:(1)同虚函数名(2)同参数表(3)同返回类型。
如基类中返回基类指针,而派生类中返回派生类指针是允许的(4)virtual(5)重载(6)静态成员函数(7)内联函数(8)构造函数8.1.7 纯虚函数定义时在函数参数表后加(1),它表明程序员对函数(2),其本质是将指向函数体的指针定为(3)。
c类的继承和多态例子

c类的继承和多态例子继承是面向对象编程中的重要概念之一,它允许一个类“继承”另一个类的属性和方法。
在C++中,继承分为三种类型:公有继承、私有继承和保护继承。
其中,公有继承是最常用的一种方式,也是实现多态的基础。
本文将通过一个例子来介绍C++中的公有继承和多态特性。
假设我们要设计一个动物园的系统,其中包含不同类型的动物。
首先,我们定义一个基类Animal,代表所有动物的共有属性和方法。
然后,派生出几个具体的动物类,如Lion(狮子)、Elephant (大象)和Monkey(猴子),它们都是Animal类的派生类。
1. 基类Animal的定义:```c++class Animal {public:Animal() {} // 构造函数virtual ~Animal() {} // 虚析构函数virtual void move() const = 0; // 纯虚函数,用于表示不同动物的移动方式protected:int age; // 年龄double weight; // 体重};```2. 派生类Lion的定义:```c++class Lion : public Animal {public:Lion(int a, double w) : Animal(), color("yellow") { age = a;weight = w;}void move() const {std::cout << "Lion is running." << std::endl;}private:std::string color; // 颜色};```3. 派生类Elephant的定义:```c++class Elephant : public Animal {public:Elephant(int a, double w) : Animal(), height(3.5) { age = a;weight = w;}void move() const {std::cout << "Elephant is walking." << std::endl; }private:double height; // 身高};```4. 派生类Monkey的定义:```c++class Monkey : public Animal {public:Monkey(int a, double w) : Animal(), num_bananas(5) {age = a;weight = w;}void move() const {std::cout << "Monkey is jumping." << std::endl;}private:int num_bananas; // 香蕉数目};```以上就是实现动物园系统的基本类定义。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
public class Example1 { public static void main(String[] args) { Human1 person = new Human1("林冲", ' 男', 30); person.think(); System.out.println(); Pupil1 aPupil = new Pupil1("001", "李 明", '男', 6); aPupil.think(); aPupil.learn(); } }
8.3 用protected声明受保护成员
关键字 protected 可修饰类的字段和方法,这些成员 能被所有派生子类直接或间接继承。 protected修饰的类成员,还能被类所在的包访问。
在例8-1中,使用了关键字protecБайду номын сангаасed修饰人类Human1 的name、sex和age字段。
虽然 protected 可以修饰字段,但类的封装性要求除 了final常量字段外,其它字段一律应为private。故 不可滥用protected修饰字段。
【例8-2】按照类封装性要求改写例8-1,以保证字段 为private。
class Human2 { private String name; private char sex; private int age; public Human2(String name, char sex, int age) { … } protected String getName(){ … } public void think(){ … } }
Student
8.4.2 用super访问父类字段和方法
除了调用父类构造方法外,super还可在子类中指代父 类对象,用于: 访问被子类隐藏的父类字段, 调用被子类覆盖的父类方法。
使用形式: super.父类字段名
super.父类方法名(可选实参表)
1、成员的隐藏
对于子类可以从父类继承的成员变量,只要子类 中声明的成员变量和父类中的成员变量同名时,子类 就隐藏了继承的成员变量;子类自己声明定义的方法 与父类方法同名是指子类重新声明定义的这个成员方 法。
【例8-3】编程,验证执行子类构造方法会自动调用父类的构造方法。 class Human3 { public Human3() { System.out.println("构造了一个人"); } }
class Pupil3 extends Human3 { public Pupil3(){ //super(); //相当于执行了 本语句 System.out.println("构造了一个学生"); } } public class Example3 { public static void main(String[] args) { Pupil3 pupil = new Pupil3(); } }
class Pupil1 extends Human1 {
//继承人类的学生类 protected String stuNo; //学号 public Pupil1(String stuNo, String name, char sex, int age) { super(name, sex, age); this.stuNo = stuNo; } public void learn( ){ } … } //学习方法
class Pupil2 extends Human2 { private String stuNo; public Pupil2(…){ … } public void learn( ){ …} } public class Example2 { public static void main(String[] args) { Human2 person = new Human2(" 林冲 ", ' 男 ', 30); person.think(); … Pupil2 aPupil = new Pupil2("001", "李明", ' 男', 6); aPupil.think(); aPupil.learn(); } }
8.4.1
8.4 关键字super 用super调用父类构造方法
类如果没有显式声明构造方法,则自动生成无参数的默 认构造方法。 子类不继承父类的构造方法,因此,子类如果想使 用父类的构造方法,必须在子类的构造方法中使用,并 且必须使用关键字 super 来表示,而且 super 必须是子类 构造方法中的头一条语句。
第8章动物类派生继承与多态
内容介绍
8.1 8.3 8.4 8.6 8.7 8.8
任务预览 用protected声明受保护成员 关键字super 多态性 本章小结 实训8:人类派生与动物类派生
8.2 继承与派生
8.5 类类型变量赋值
8.1 任务预览
本章实训程序运行结果:
8.2 继承与派生
计算机世界与自然界一样,类之间也有继承和派生关系。 运用继承与派生能达到代码重用、简化编程的目的。语 法:
class 子类名 extends 父类
[public] [abstract] [final] { ... }
类的单一继承关系形成了清晰的层次结构,树状图如下:
【例8-1】编写人类。再编写继承人类的学生类,学生 类还拥有学号字段和学习方法。构造人类和学生类的对 象,输出有关信息。 class Human1 { //人类 protected String name; protected char sex; protected int age; public Human1(String name, char sex, int age) { = name; this.sex = sex; this.age = age; } public void think(){ //思考 方法 System.out.println(name + "在思考..."); } }