C++--继承与多态(郑莉课件)
合集下载
C继承多继承PPT课件
{ public:
void g();
void h();
};
若有C obj;
则对函数 f()的访问是二义的: obj.f();
第9页/共20页
二义性和支配原则
1. 同名成员的二义性
• 不同基类中有同名函数,使用基类名可避免这种二义:
obj.A::f(); obj.B::f();
void C : : f ( ) { A : : f ( ); // B : : f ( ); }
{ D dd ; }
第17页/共2Байду номын сангаас页
class A class B
class A class C
class D
两次调用 A的构造函数
7.5.2
虚基类
例8 虚继承的测试
#include < iostream.h >
class A
{ public :
A ( ) { cout << "class A" << endl ; }
B B1
B B2 C
建立 C 类的对象时,B 的 构造函数将被调用两次: 分别由B1调和 B2 调用, 以初始化 C 类的对象中所 包含的两个 B 类的子对象
第13页/共20页
虚基类
➢ 如果在多条继承路经上有一个公共的基类,那么在继承 路经的某处汇合点,这个公共基类就会在派生类的对象中 产生多个基类子对象 ➢ 要使这个公共基类在派生类中只产生一个子对象,必须 将这个基类 声明为虚基类。 ➢ 虚基类声明使用关键字 virtual
{
public :
Derived ( int, char, double ) ;
第5章 继承性、多态PPT课件
• sealed class MyClass •{ •} • 当程序中密封了某个类时,其他类是不能继承该
类的,如代码所示。 • 【本示例参考:\示例代码\Chap05\SealedClass1】
2020/10/13
9
5.2.5 方法的隐藏
• 【本节示例参考:\示例代码 \Chap05\HidingMethod】
• operand is type
• 在上述定义中,当type是一个类,而operand也是该类型、或继承 了该类型、或封箱到该类型中时结果为true;当type是一个接口 类型,而operand也是该类型,或者执行该接口的类型结果也为 true;当type是一个值类型,而operand也是该类型,或者被拆箱 到该类型中时结果也为true。如下面的一个简事例:
• 还有一种方法可以实现在派生类中的覆盖,即new 关键字。这种过程叫做方法的隐藏。但是,派生 类和非抽象类的基类方法必须有相同的方法。代 码演示了如何实现方法的隐藏。
• 运行结果: • Study方法被调用 • Person方法被调用 • 方法隐藏的作用就是可以改变基类的方法。如果
一个派生类型被强制向上转换为基类型,基类型 的方法将被调用。
• C# 2008程序是通过使用名空间来组织的。其不仅 可以是应用程序的内部结构体系,同样也可以是 外部结构体系。如果程序中的一些元素要被导出 到其他程序,可以使用命名空间。程序中免不了 会出现错误,这时就会用到C#语言的异常处理机 制。
2020/10/13
1
5.1 继承机制
• 面向对象的重要机制之一继承是可以使用以前建 造类的方法和属性。通过简单的程序代码来建造 功能强大的类,不仅会节省很多编程时间,而且 还可以减少代码出错的机会。
类的,如代码所示。 • 【本示例参考:\示例代码\Chap05\SealedClass1】
2020/10/13
9
5.2.5 方法的隐藏
• 【本节示例参考:\示例代码 \Chap05\HidingMethod】
• operand is type
• 在上述定义中,当type是一个类,而operand也是该类型、或继承 了该类型、或封箱到该类型中时结果为true;当type是一个接口 类型,而operand也是该类型,或者执行该接口的类型结果也为 true;当type是一个值类型,而operand也是该类型,或者被拆箱 到该类型中时结果也为true。如下面的一个简事例:
• 还有一种方法可以实现在派生类中的覆盖,即new 关键字。这种过程叫做方法的隐藏。但是,派生 类和非抽象类的基类方法必须有相同的方法。代 码演示了如何实现方法的隐藏。
• 运行结果: • Study方法被调用 • Person方法被调用 • 方法隐藏的作用就是可以改变基类的方法。如果
一个派生类型被强制向上转换为基类型,基类型 的方法将被调用。
• C# 2008程序是通过使用名空间来组织的。其不仅 可以是应用程序的内部结构体系,同样也可以是 外部结构体系。如果程序中的一些元素要被导出 到其他程序,可以使用命名空间。程序中免不了 会出现错误,这时就会用到C#语言的异常处理机 制。
2020/10/13
1
5.1 继承机制
• 面向对象的重要机制之一继承是可以使用以前建 造类的方法和属性。通过简单的程序代码来建造 功能强大的类,不仅会节省很多编程时间,而且 还可以减少代码出错的机会。
C语言程序设计清华大学郑莉PPT课件
向 • 是现实世界中一个实际存在的事物。
• 可以是有形的(比如一辆汽车),也可以是无形的(比如一项计划)。
对 • 是构成世界的一个独立单位,具有:
象 • 静态特征:可以用某种数据来描述
的 • 动态特征:对象所表现的行为或具有的功能
方
法
第13页/共702页
面向对象的基本概念
面
——对象
向
对 象
• 面向对象方法中的对象:
信
息
的 表
┌控制信息 │
示 信息┤
与
│
存
┤
│
储
└ 浮点数 └数据信息
┌ 字符数据
息┤
第27页/共702页
┌ 指令 ┤ └ 控制字
┌ 定点数 ┌ 数值信息 ┤ │ └ 非数值信
└逻
计算机的数字系统
信 息 的
表 示
• 计算机采用的是二进制数字系统。 • 基本符号:0、1 • 进位原则:逢二进一 • 优点:
维护
面 将 软 件 交 付 使 用 后 , 工 作 并 没 有 完 结 , 还 要 根 据 软 件 的 运 行 情 况 和 用 户 的 需 求 , 不 断 改 进 系 统 。 向 使 用 面 向 对 象 的 方 法 开 发 的 软 件 , 其 程 序 与 问 题 域 是 一 致 的 , 因 此 , 在 维 护 阶 段 运 用 面 向 对 象 的 方 法
发生联系。
对 象 的 方 法
第17页/共702页
面向对象的基本概念
面 — — 继 承 • 继承对于软件复用有着重要意义,是面向对象技术能够提高软件开发效率的重要原因之一。 向 • 定义:特殊类的对象拥有其一般类的全部属性与服务,称作特殊类对一般类的继承。 对 • 例如:将轮船作为一个一般类,客轮便是一个特殊类。
继承与多态课件ppt
按他们在类定义中出现的先后顺序:先定义者先 构造。
• 类的对象成员与类的一般数据成员的构造顺序?
先构造类的对象成员,再构造一般数据成员(执 行类自身的构造函数体)。
• 构造顺序与析构顺序的关系?
二者顺序相反:先构造者,后析构。
继承
多继承:一个类从多个基类派生,这样的继
承结构称为多继承
Father
int leg; int body; Public: …… };
Class teacher:public human { string name; h1 Public: …… };
• 派生类对象的空间占用≥基类对象的空间占用
继承
类内的访问控制:派生类是否能访问所有基类 成员?
对于基类的私有成员,派生类不能直接访问 protected的作用:只能让子类访问而不能让
• 练习2:设计一个虚基类base,包含姓名和 年龄私有数据成员以及相关的成员函数, 由它派生出领导类leader,包含职务和部门 私有数据成员以及相关的成员函数。再由 base派 生出工程师类engineer,包含职称 和专业私有数据成员以及相关的成员函数。 然后由leader和engineer类派生出主任工程 师类chairman。采用一些数据进行测试。
派生类(子类)
human teacher
通常有关系:子类 is a 父类
继承
Inheritance
继承
继承
Student
Employee
GradStudent
Manager
Fig.1 单重继承
Vehicle
Father
Mather
Car Coupe Fig.2 多层继承
Child
Fig.3 多重继承
• 类的对象成员与类的一般数据成员的构造顺序?
先构造类的对象成员,再构造一般数据成员(执 行类自身的构造函数体)。
• 构造顺序与析构顺序的关系?
二者顺序相反:先构造者,后析构。
继承
多继承:一个类从多个基类派生,这样的继
承结构称为多继承
Father
int leg; int body; Public: …… };
Class teacher:public human { string name; h1 Public: …… };
• 派生类对象的空间占用≥基类对象的空间占用
继承
类内的访问控制:派生类是否能访问所有基类 成员?
对于基类的私有成员,派生类不能直接访问 protected的作用:只能让子类访问而不能让
• 练习2:设计一个虚基类base,包含姓名和 年龄私有数据成员以及相关的成员函数, 由它派生出领导类leader,包含职务和部门 私有数据成员以及相关的成员函数。再由 base派 生出工程师类engineer,包含职称 和专业私有数据成员以及相关的成员函数。 然后由leader和engineer类派生出主任工程 师类chairman。采用一些数据进行测试。
派生类(子类)
human teacher
通常有关系:子类 is a 父类
继承
Inheritance
继承
继承
Student
Employee
GradStudent
Manager
Fig.1 单重继承
Vehicle
Father
Mather
Car Coupe Fig.2 多层继承
Child
Fig.3 多重继承
C 程序设计 教学课件 ppt 第11章_多态性
▫ 分析
这个结果和例10-7的输出结果很不一样。Base1声明Show
为基函数,派生类Base2,C重写了该函数,通过向上转
型,分别传递Base1,Base2,C的指针给CallShow函数
时,虽然在CallShow函数中的语句是“pb1->Show();”,
其中pb1被声明为Base1的指针,但是调用的函数确分别
▫ 参数多态:与将在第14章中介绍的类模板相关联 ▫ 前两种称为专用多态,后两种称为通用多态
C++程序设计,郑莉,清华大学 4
11.2 虚函数
11.2.1 一般虚函数成员
• 将类的某个成员函数用virtual关键字声明得到的函 数就是虚函数
• 定义格式为:
virtual 返回类型 函数名(形参表) {
class C:public Base {
public:
C() { ip = new int(0); } //类C构造函数,初始化成员
~C();
//类C析构函数
private:
int * ip; };
C::~C() {
delete ip;
cout<<"ip has been deleted"<<endl;
};
class C:public Base2 {
void Show() { cout<<"C::Show()"<<endl; }
//公共函数Show
};
C++程序设计,郑莉,清华大学 6
11.2 虚函数
11.2.1 一般虚函数成员
void CallShow(Base1* pb1) { //全局函数,参数为Base1的指针
C继承与多态性.ppt
int main()
//基类Point类的声明
{ CRect rect;
class Point
rect.InitR(2,3,20,10);
{private:
//通过派生类对象访问基类公有成员
float X,Y;
rect.Move(3,2);
public:
cout <<rect.GetX()<<','
基类名
8
单继承派生类的声明格式:
class <派生类名> : <继承方式><基类名> {
<派生类新增加的数据成员> <派生类新增加的成员函数> };
多继承派生类的定义格式为:
class <派生类名> : <继承方式1><基类名1>,<继 承方式2><基类名2>,…
{ <派生类新增加的数据成员>
<派生类新增加的成员函数> };
CUserDoc CWinApp
CWnd
CView
CFrameWnd
CDialog
CUserApp
CUserView CMainFrame
CUserDialog
MFC关键类的层次体系
6
多继承:一个派生类继承两个或多个基类。
7
派生类的定义方法:
前例中,已声明过一个基类Student,在此 派生基类础名 上通过单继承建立一个派生类Student1。
方法二:在派生类声明同名成员——覆盖基类成 员。!!注意,对于成员函数,不仅要同名还要参数 个数和类型都相同。(请问,这是为什么?)
《继承与多态》课件
可读性和复用性,减少代码冗余。
总结
4
继承和多态是面向对象编程中重要的 思想和方法,对于软件开发具有重要
意义。
多态可以通过方法重写和方法重载来实现, 使不同的对象可以对同一方法表现出不同 的行为。
3 多态的好处
4 多态的注意事项
多态提高了代码的灵活性和可扩展性,使 代码更易于维护和扩展。
在使用多态时,需要注意方法的参数类型 和返回值类型,以避免类型错误导致的运 行时错误。
三、继承与多态的实例
实例介绍
通过一个学校的班级管理系统实例,演示继承和 多态的实际应用。
《继承与多态》PPT课件
本课程介绍继承与多态的概念和应用。通过丰富的实例和实践演示,帮助学 生深入理解这些重要的面向对象编程概念。
一、继承
什么是继承
继承是面向对象编程中的重要概念,允许子 类继承父类的属性和方法。
继承的实现方式
继承可以通过使用关键字extends将子类与父 类联系起来,形成继承关系。
实例演示
展示如何通过继承和多态处理学生和老师的不同 操作,并实现班级管理的各项功能。
四、总结
1
继承与多态的异同
继承和多态都是面向对象编程的核心
适用场景
2
概念,但它们的实现方式和应用场景 有所不同。
继承适用于父子类之间的继承关系,
而多态适用于处理不同对象的同一操
作。
3
使用技巧
合理应用继承和多态可以提高代码的
继承的好处
通过继承,子类可以重用父类的代码,提高 开发效率,并实现代码的复用。
继承的注意事项
在继承中,需要注意继承层级、构造函数的 调用以及方法重写等问题,以确保正确的继 承操作。
二、多态
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
29
派 生 类 的 构 造 、 析 构 函 数
继承时的构造函数
派生类有时需要声明自己的构造函数。 声明构造函数时,只需要对本类中新 增成员进行初始化,对继承来的基类 成员的初始化,系统将自动调用基类 构造函数完成。 派生类的构造函数需要给基类的构造 函数传递参数,如果不传递,基类将 自动使用不带任何参数的构造函数。
};
B::B() { b=0; cout<<"B's default constructor called."<<endl; } B::B(int i) {b=i; cout<<"B's constructor called." <<endl; } B::~B() { cout<<"B's destructor called."<<endl; } void B::Print() const { cout<<b<<endl; }
通过基类对象名、指针只能使用从基 类继承的成员
例7-4 类型兼容规则举例
类 型 兼 容
#include <iostream> using namecpace std; class B0 //基类B0声明 { public: void display(){cout<<"B0::display()"<<endl;} //公有成员函数 };
C++语言程序设计
第七章 继承与派生
清华大学 郑 莉
本章主要内容
类的继承与派生 类成员的访问控制 单继承与多继承 派生类的构造、析构函数 类成员的标识与访问
类的继承与派生
保持已有类的特性而构造新类的过程 称为继承。 在已有类的基础上新增自己的特性而 产生新类的过程称为派生。 被继承的已有类称为基类(或父类)。 派生出的新类称为派生类(或子类)。
private:
};
//新增私有数据成员
float W,H;
11
#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; }
class A { protected: int x; } int main() { A a; a.x=5; //错误 }
class A { protected: int x; } class B: public A{ public: void Function(); }; void B:Function() { x=5; //正确 }
派 生 类 的 构 造 、 析 构 函 数
单一继承时的构造函数
派生类名::派生类名(基类所需的形参, 本类成员所需的形参):基类名(参数表)
{
本类成员初始化赋值语句; };
派 单一继承时的构造函数举例 生 类 #include<iostream> 的 using namecpace std; 构 class B{ public: 造 B(); 、 B(int i); 析 ~B(); 构 void Print() const; private: 函 int b; 数
class Rectangle: public Point //派生类声明 {
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;}
B0::display() B0::display()
25
基类与派生类的对应关系
单 继 承 与 多 继 承
单继承
– 派生类只从一个基类派生。
多继承
– 派生类从多个基类派生。
多重派生
– 由一个基类派生出多个不同的派生类。
多层派生
– 派生类又作为基类,继续派生新的类。
多继承时派生类的声明
19
例子:补充
#include <iostream> using namespace std; class A{ protected: //改成public,或者private可不可以? int a; }; class B:public A{ // 改成protected,或者private可不 可以? public: void showB(){cout<<a<<endl;} }; class C:public B{ public: void showC(){cout<<a<<endl;} };
int main(){ B b; b.showB(); system("Pause"); //cout<<b.a<<endl; }
类型兼容规则
类 型 兼 容
一个公有派生类的对象在使用上可以 被当作基类的对象,反之则禁止。具 体表现在:
– 派生类的对象可以被赋值给基类对象。 – 派生类的对象可以初始化基类的引用。 – 指向基类的指针也可以指向派生类。
12
私有继承(private)
类 成 员 的 访 问 控 制
基类的public和protected成员都以 private身份出现在派生类中,但基类 的private成员不可直接访问。 派生类中的成员函数可以直接访问基 类中的public和protected成员,但 不能直接访问基类的private成员。 通过派生类的对象不能直接访问基类 中的任何成员。
void A::setA(int x) { a=x; } void B::setB(int x) { b=x; }
void C::setC(int x, int y, int z) { //派生类成员直接访问基类的
//公有成员
setA(x); setB(y); c=z; } //其它函数实现略
int main() { C obj; obj.setA(5); obj.showA(); obj.setC(6,7,9); obj.showC(); // obj.setB(6); 错误 // obj.showB(); 错误 return 0; }
派生类的声明
类 的 继 承 与 派 生
class 派生类名:继承方式 基类名 { 成员声明; }
继承方式
类 成 员 的 访 问 控 制
不同继承方式的影响主要体现在:
– 派生类成员对基类成员的访问权限 – 通过派生类对象对基类成员的访问权限
三种继承方式
– 公有继承 – 私有继承 – 保护继承
公有继承(public)
例7-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; };
15
保护继承(protected)
类 成 员 的 访 问 控 制
基类的public和protected成员都以 protected身份出现在派生类中,但 基类的private成员不可直接访问。 派生类中的成员函数可以直接访问基 类中的public和protected成员,但 不能直接访问基类的private成员。 通过派生类的对象不能直接访问基类 中的任何成员
class B1: public B0 { public: void display(){cout<<"B1::display()"<<endl;} }; class D1: public B1 { public: void display(){cout<<"D1::display()"<<endl;} }; void fun(B0 *ptr) { ptr->display();//"对象指针->成员名" }
24
void main() //主函数 { B0 b0; //声明B0类对象 B1 b1; //声明B1类对象 D1 d1; //声明D1类对象 B0 *p; //声明B0类指针 p=&b0; //B0类指针指向B0类对象 fun(p); p=&b1; //B0类指针指向B1类对象 fun(p); p=&d1; //B0类指针指向D1类对象 fun(p); 运行结果: B0::display() }
类 成 员 的 访 问 控 制
基类的public和protected成员的访问 属性在派生类中保持不变,但基类的 private成员不可直接访问。 派生类中的成员函数可以直接访问基类 中的public和protected成员,但不能 直接访问基类的private成员。 通过派生类生成的对象只能访问基类的 public成员。