第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成员。 成员。 成员
不同继承方式的影响主要体现在: 不同继承方式的影响主要体现在:
派生类成员对基类成员的访问权限 派生类成员对基类成员的访问权限 成员 通过派生类对象 对象对基类成员的访问权限 通过派生类对象对基类成员的访问权限
Python的继承与多态

Python的继承与多态一、概述继承和多态是面向对象程序设计的两个基本概念。
继承是指一个类可以从另一个类继承属性和方法。
多态是指同一个方法可以根据传入的不同参数表现出不同的行为。
Python作为一种面向对象编程语言,继承和多态在其语言中得到了非常好的支持。
本文将分别从继承和多态两个方面来讨论Python中的这两个概念,并探究其在Python程序设计中的应用。
二、继承的应用1.基本概念继承是指一个类可以从另一个类继承属性和方法。
在Python中,继承可以通过在类定义时在类名后加上要继承的父类名称来实现。
例如:```class Animal:def __init__(self, name): = namedef age(self):return 0class Dog(Animal):def age(self):return 2```在这个例子中,我们定义了一个父类Animal,该类有一个属性name和一个方法age,其中age方法返回0。
然后我们定义了一个子类Dog,它继承了Animal并覆盖了其age方法,使其返回2。
2.使用super函数在上面的例子中,我们通过重新定义方法来覆盖父类的方法。
但是,如果我们想在子类中保留父类方法的一些行为,该怎么办呢?这时就需要使用super函数。
super函数可以用来调用父类的方法,让子类继承父类的行为。
例如:```class Animal:def __init__(self, name): = namedef age(self):return 0class Dog(Animal):def age(self):return super().age() + 2```在这个例子中,我们重新定义了Dog类的age方法,在其中调用了父类Animal的age方法,并给其加上了2。
这样就在保留原有的父类行为的同时,给其添加了新的行为。
3.实现多态继承不仅可以使子类继承父类的行为,还可以通过多态来实现不同的子类表现出不同的行为。
第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建立的控制台应 用程序项目中,编写代码,测试类 的多态性。
第8章动物类派生——继承与多态

能力目标: 理解类的继承,能编写类及其派生子类。 理解多态含义,理解上转型对象,能在子类中重写父 类的同名方法。 能运用继承与多态编写人类派生学生类、动物类派生 马类等程序。
内容介绍
8.1 8.2 8.3 8.4 8.5 8.6 8.7 8.8
/
8.5.3 兄弟类对象不能相互替换
如果鸟类、马类和鱼类都继承动物类,则它们是同一层次的, 是兄弟(姐妹)类。 显然,鸟不是马,鸟也不是鱼,因此,不能把鸟对象赋给马 类或鱼类声明的变量。 同一层次的兄弟类变量之间不能相互赋值,即兄弟类对象间 不能相互替换。
/
8.6 多态性
类的多态性: 一是类本身, 二是作为父类专用于派生, 三是通过实现接口而充当接口的实例类型。 多态主要反映在方法重写(覆盖)和方法重载这两个方面。
8.4 关键字super
/
8.4.2 用super访问父类字段和方法
除了调用父类构造方法外,super还可在子类中指代父类对 象,用于: 访问被子类隐藏的父类字段, 调用被子类覆盖的父类方法。 使用形式: super.父类字段名 super.父类方法名(可选实参表)
/
8.5.1 子类对象的上转型对象
}
/
续例8-4
public class Example4 { public static void main(String[] args) { System.out.println(" ==== 学生的上转型对象 ====="); Human4 human = new Pupil4("001", "李明"); System.out.println("该对象属于" + human.typeName); System.out.println(human.like()); human.think(); //human.learn(); //出错,只能((Pupil4)human).learn(); … 上转型对象还原为学生对象 Pupil4 pupil = (Pupil4)human; System.out.println("该对象属于" + pupil.typeName); System.out.println(pupil.like()); pupil.think(); pupil.learn(); } }
3《C# 3.0项目导向与实训程序设计教程》第8章动物类派生 继承与多态

动物类派生——继承与多态
能力目标: 1. 理解类的继承,学会使用基类编写派生类。 2. 理解关键字 new、virtual、override、protected 等的作用,理解多态含义。 3. 能运用继承与多态性编写哺乳动物类派生马类鲸鱼类、人类派生学生类等应用程序。
8.1
项目预览
本章要完成的哺乳动物类派生马类和鲸鱼类、人类派生学生类等 WPF 应用程序项目, 运行界面如图 8-1 所示。
(a)
(b)
(c)
图 8-10 哺乳动物类派生马类和鲸鱼类、人类派生学生类 WPF 项目设计界面
提示:部分代码参考如下。 class Mammal //哺乳动物类 { public string Name { get; set; } //名称属性 public Mammal() { TypeName = "哺乳动物类";} //默认构造函数 public Mammal(string name) { ... } //带名称参数的构造函数 public string Breathe() { return Name + "正在呼吸..."; } //呼吸方法 public string Suckle() { ... } //哺乳方法 public virtual string Go() { ... } //虚的行走方法 ... } class Horse : Mammal //继承哺乳动物的马类 { public new string Suckle() { return Name + "正在被人工喂奶..."; } //新的哺乳方法 public string Trot() { ... } //小跑马方法 public override string Go() { return Name + "正在奔跑..."; } //重写的行走方法 ... } ... private void buttonMammal_Click(object sender, RoutedEventArgs e) { Mammal aMammal = new Mammal("怪兽A"); textBoxMammal.Text = "构造了一个" + ; textBoxMammal.Text += "\n它属于" + aMammal.TypeName;
第8章_继承和派生

};
派生类中含有对象成员时,其构造函数的声明格式如下:
派生类的构造函数名称(参数表): 基类的构造函数名(参数表),
对象成员名1(参数表),…对象成员名N(参数表)
{
//…
//派生类构造函数体
}
class Circle2 :public Point
{
double radius;
Point P1; //基类Point的对象成员P1
{
protected
}; void main() { son sonobj;
sonobj.get(); }
8.3 派生类的构造函数和析构函数
派生类的构造函数名称(参数表):基类的构造函数名(参数表) {
… }
class Point
{ int x,y;
public:
Point(int a,int b) //基类的构造函数
Circle (double r,int a,int b):Point(a,b)
//派生类的构造函数
{ radius =r;
cout<<”Constructing Circle class \n”;
}
~ Circle () //派生类的析构函数
{ cout<<”Destructing Circle class \n”; }
使用protected声明的称为保护成员。任何一个类的保护成员 仅可以被其自己和派生类的所有非静态成员函数和友元函数直 接访问,也就是说其他的外部函数是不能访问它的。因此,对 于那些既要对外界隐藏,又要能被派生类访问的成员,可以将 它们声明为保护成员。
8.2.3三种派生方式的定义
class 派生类名 : 派生存取说明符 基类名 { //派生类新增的数据成员和成员函数 }; 1.私有(private)派生
第八章 继承与多态习题(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)。
【例8-2】按照类封装性要求改写例8-1,以保 证字段为private。
15
8.3 用protected声明受保护成员
虽然protected可以修饰字段,但类的封装性要求除了final 常量字段外,其它字段一律应为private。故不可滥用 protected修饰字段。 例8-2中,调用了Pupil2的构造方法创建一个学生对象,使 用了name等字段
24
8.5.1 子类对象的上转型对象
8.5 类类型变量赋值
子类由父类派生,可把子类对象赋给父类声明的变量。如:
Human human = new Pupil();
或者:
Human human; Pupil pupil = new Pupil(); human = pupil;
25
8.5.1 子类对象的上转型对象
第8章 动物类派生 ——继承与多态
能力目标: 理解类的继承,能编写类及其派生子类。 理解多态含义,理解上转型对象,能在子类中重写父 类的同名方法。 能运用继承与多态编写人类派生学生类、动物类派生 马类等程序。
1
内容介绍
8.1 8.2 8.3 8.4 8.5 8.6 8.7 8.8
}
13
8.3 用protected声明受保护成员
关键字protected可修饰类的字段和方法,这些成员能被所 有派生子类直接或间接继承。 protected修饰的类成员,还能被类所在的包访问。 在例8-1中,使用了关键字protected修饰人类Human1的 name、sex和age字段。 虽然protected可以修饰字段,但类的封装性要求除了final 常量字段外,其它字段一律应为private。故不可滥用 protected修饰字段。
8.5 类类型变量赋值
这种由父类变量引用的子类对象就是上转型对象。 上转型对象具有如下特征: (1)上转型对象不能操作子类新增的成员字段和成员方法。 (2)上转型对象能使用父类被继承或重写的成员方法、被继 承或隐藏的成员变量。 (3)如果子类重写了父类的方法,则上转型对象调用该方法 时一定是重写后的方法(多态性)。 (4)如果子类重新定义了父类的同名字段,即隐藏了父类的 字段,则上转型对象访问该字段时必定是父类本身的字段。
编写继承人类的学生类Pupil
有私有的学号字段
获取该字段的受保护方法 公共的构造方法 学习方法
编写继承学生类的大学生类Student
有公共的构造方法、自学方法和输出数据方法
20
练习-续
最后设计一个入口主类,构造若干个大学生,把他们的数据 和行为列举出来。
21
Human类
26
【例8-4】编程,测试子类对象的上转型对象以 及还原后的子类对象。
class Human4 { //人类 private String name; //姓名 public static final String typeName = "人类"; //类名 public Human4(String name){ //构造方法 = name; } protected String getName(){ //获取姓名方法 return name; } public void think(){ //思考方法 System.out.println(name + "在思考..."); } public String like(){ //爱好方法 return "爱好因人而异"; } }
7
【例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 + "在思考..."); }
12
【例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 + "在思考..."); }
}
9
续例8-1
编写继承人类的学生类,学生类还拥 有学号字段和学习方法。
//继承人类的学生类 //学号
class Pupil1 extends Human1 { protected String stuNo;
public Pupil1(String stuNo, String name, char sex, int age){ super(name, sex, age); this.stuNo = stuNo; }
任务预览 继承与派生 用protected声明受保护成员 关键字super 类类型变量赋值 多态性 本章小结 实训8:人类派生与动物类派生
2
8.1 任务预览-1
本章实训程序运行结果:
3
8.1 任务预览-2
本章实训程序运行结果:
4
8.2 继承与派生
计算机世界与自然界一样,类之间也有继承和派生关系。 运用继承与派生能达到代码重用、简化编程的目的。 语法: 可选public 可选abstract 可选final class 子类 extends 父类 { ... } 子类继承父类,父类派生子类。
public void learn() //学习方法 { System.out.println(getName() + ”在学习…”); }
}
23
Student类
class Student extends Pupil{ public Student(…){ super(…); } public void study(){ System.out.println( … + “在自学…”); } public String toString() { return String.format(“所构造大学生信息: %s号%s, %c, %d 岁”, getStuNo(), getName(), …); } }
class Human1 { private String name; private char sex; private int age; //人类
public Human(String name, char sex, int age){ = name; this.sex = sex; this.age = age; } public void think(){ //思考方法 System.out.println(name + "在思考..."); }
14
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(){ … } } 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(); } }
18
8.4.2 用super访问父类字段和方法
除了调用父类构造方法外,super还可在子类中指代父类对 象,用于: 访问被子类隐藏的父类字段, 调用被子类覆盖的父类方法。 使用形式: super.父类字段名 super.父类方法名(可选实参表)
19
练习
编写人类Human
有私有的姓名、性别和年龄字段 定义获取各个私有字段的受保护方法 定义公共的构造方法和思考方法
5
继承的单一性
类的单一继承关系
一个类只能有一个父类 一个父类可以派生多个子类
形成了清晰的层次结构,树状图如下:
6
Object类
Object类
所有类的祖先类
在ng包中 所有类直接或间接继承Object类
若没有显示继承别的类,则默认继承Object类:
class Human extends Object { … } Object类的非私有成员通过派生成为个各类的成员 toString方法 equals方法 …