07--继承与派生

本章主要内容类的继承 类成员的访问控制 单继承与多继承 派生类的构造、析构函数 类成员的标识与访问
展开查看详情

1.C++语言程序设计 第七章 继承与派生 信息工程学院 王红平 1

2.C++语言程序设计 本章主要内容  类的继承  类成员的访问控制  单继承与多继承  派生类的构造、析构函数  类成员的标识与访问 2

3.C++语言程序设计 类的继承与派生  保持已有类的特性而构造新类的过程 称为继承。  在已有类的基础上新增自己的特性而 产生新类的过程称为派生。  被继承的已有类称为基类(或父类)。  派生出的新类称为派生类。 3

4.C++语言程序设计 继承与派生问题举例 类 交 通工具 的 继 承 汽车 与 派 小汽车 卡车 旅行车 生 工具车 轿车 面包车 4

5.C++语言程序设计 继承与派生问题举例 类 的 动物 继 承 与 派 猴子 猫科 猫 鸟 生 狮子 虎 猎豹 5

6.C++语言程序设计 继承与派生问题举例 类 的 几 何形状 继 承 与 派 生 圆 矩形 6

7.C++语言程序设计 继承与派生问题举例 类 的 雇员 继 承 与 兼职技术人员 管理人员 销售人员 派 生 销售经理 7

8.C++语言程序设计 继承与派生的目的 类 的  继承的目的:实现代码重用。 继 承  派生的目的:当新的问题出现,原有 与 程序无法解决(或不能完全解决)时, 派 需要对原有程序进行改造。 生 8

9.C++语言程序设计 派生类的声明 类 的 class 派生类名:继承方式 基类名 继 承 { 与 成员声明; 派 } 生 9

10.C++语言程序设计 继承方式 类 成  不同继承方式的影响主要体现在: 员 – 派生类成员对基类成员的访问权限 的 – 通过派生类对象对基类成员的访问权限 访  三种继承方式 问 – 公有继承 控 – 私有继承 制 – 保护继承 10

11.C++语言程序设计 公有继承(public) 类 成  基类的public和protected成员的访问 员 属性在派生类中保持不变,但基类的 private成员不可直接访问。 的 访  派生类中的成员函数可以直接访问基类 问 中的public和protected成员,但不能 控 直接访问基类的private成员。 制  通过派生类的对象只能访问基类的 public成员。 11

12.C++语言程序设计 例7-1 公有继承举例 类 class Point //基类Point类的声明 成 {public: //公有函数成员 员 Point(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; }; 12

13.class Point3D: public Point //派生类声明 { public: //新增公有函数成员 Point3D(float x, float y, float z) : Point(x, y) {Z=z;} //显示调用基类函数 float GetZ() {return Z;} private: //新增私有数据成员 float Z; }; 13

14.#include<iostream> #include<cmath> using namecpace std; int main() { Point3D pt3d(2,3,20); //通过派生类对象访问基类公有成员 pt3d.Move(3,2); cout<<pt3d.GetX()<<',' <<pt3d.GetY()<<',' <<pt3d.GetZ()<<endl; return 0; } 14

15.C++语言程序设计 私有继承(private) 类 成  基类的public和protected成员都以 员 private身份出现在派生类中,但基类 的 的private成员不可直接访问。 访  派生类中的成员函数可以直接访问基 类中的public和protected成员,但 问 不能直接访问基类的private成员。 控  通过派生类的对象不能直接访问基类 制 中的任何成员。 15

16.C++语言程序设计 例7-2 私有继承举例 类 class Point3D: private Point //派生类声明 成 {public: //新增外部接口 员 Point3D(float x, float y, float z) : Point(x,y) {Z = z;} //访问基类公有成员 的 void Move(float xOff, float yOff) 访 {Point::Move(xOff,yOff);} float GetX() {return Point::GetX();} 问 float GetY() {return Point::GetY();} 控 float GetZ() {return Z;} 制 private: float //新增私有数据 Z; }; 16

17.#include<iostream> #include<cmath> using namecpace std; int main() { //通过派生类对象只能访问本类成员 Point3D pt3d(2,3,20); pt3d.Move(3,2); cout<<pt3d<<endl; return 0; } 17

18.C++语言程序设计 保护继承(protected) 类 成  基类的public和protected成员都以 员 protected身份出现在派生类中,但 的 基类的private成员不可直接访问。 访  派生类中的成员函数可以直接访问基 类中的public和protected成员,但 问 不能直接访问基类的private成员。 控  通过派生类的对象不能直接访问基类 制 中的任何成员 18

19.C++语言程序设计 protected 成员的特点与作用 类 成  对建立其所在类对象的模块来说,它 员 与 private 成员的性质相同。 的  对于其派生类来说,它与 public 成 访 员的性质相同。 问  既实现了数据隐藏,又方便继承,实 控 现代码重用。 制 19

20.C++语言程序设计 例7-3 protected 成员举例 类 class A { 成 protected: 员 int x; 的 } 访 int main() 问 { 控 A a; 制 a.x=5; //错误 } 20

21.class A { protected: int x; } class B: public A{ public: void Function(); }; void B:Function() { x=5; //正确 } 21

22.C++语言程序设计 类型兼容规则 类  一个公有派生类的对象在使用上可以 型 被当作基类的对象,反之则禁止。具 兼 体表现在: 容 – 派生类的对象可以被赋值给基类对象。 – 派生类的对象可以初始化基类的引用。 – 指向基类的指针也可以指向派生类。  通过基类对象名、指针只能使用从基 类继承的成员 22

23.C++语言程序设计 例7-4 类型兼容规则举例 类 通用显示程序的幻想 型 #include <iostream> 兼 using namecpace std; 容 class B0 //基类B0声明 { public: void display(){cout<<"B0::display()"<<endl;} //公有成员函数 }; 23

24.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

25.int 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() B0::display() B0::display() 25

26.C++语言程序设计 基类与派生类的对应关系 单  单继承 继 – 派生类只从一个基类派生。 承 与  多继承 多 – 派生类从多个基类派生。 继  多重派生 承 – 由一个基类派生出多个不同的派生类。  多层派生 – 派生类又作为基类,继续派生新的类。 26

27.C++语言程序设计 多继承时派生类的声明 单 继 class 派生类名:继承方式1 基类名1, 承 继承方式2 基类名2,... 与 { 多 成员声明; 继 } 承 注意:每一个“继承方式”,只用于限制 对紧随其后之基类的继承。 27

28.C++语言程序设计 多继承举例 单 class A{ private: 继 public: int b; 承 void setA(int); }; class C : public A, private B{ void showA(); 与 private: public: 多 int a; void setC(int, int, int); 继 }; void showC(); 承 class B{ public: private: int c; void setB(int); }; void showB(); 28

29.void A::setA(int x) int main() { a=x; } { C obj; void B::setB(int x) obj.setA(5); { b=x; } obj.showA(); obj.setC(6,7,9); void C::setC(int x, int y, int obj.showC(); z) // obj.setB(6); 错误 { //派生类成员直接访问基类的 // obj.showB(); 错误 //公有成员 return 0; setA(x); } setB(y); c=z; } //其他函数实现略 29