在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
继承(inheritance)是软件重用的一种方式,程序员通过继承可以吸收已有类的数据和行为来创建新类,并可以添加新的数据和行为来增强类的功能。创建新类时,并不需要创建全新的数据和成员函数,我们可以指明这个新类应当继承现有类的成员。此时,现有的类称为“基类”,继承实现的新类称为“派生类”。派生类代表了一组更加特殊化的对象,它包含了从基类继承来的行为,并进行了扩充。 介绍:类是对现实中事物的抽象,类的继承和派生的层次结构则是对自然界中事物分类、分析的过程在程序设计中的体现。下图说明了某个公司雇员的派生关系。位于最高层的雇员其抽象程度最高,是最具一般性的概念。最下层抽象程度最低,最具体。从上层到下层是具体化的过程,从下层到上层是抽象话的过程。面向对象设计中上层与下层是基类与派生类的关系。
依照面向对象的理念:当某个概念用语言的基本类型不能具体表示时,就应当定义一个新的类型(class)。一个概念一般不是独立存在的,通常与其相关的概念共存,以此发挥更大的作用。当某个概念与其他概念之间存在关系时,应当在相应的类型之间也表示出这样的关系。 类之间的关系主要有以下两种: 一个车有四个轱辘一个引擎。 这里的关系实质上是聚集中的组合。整体拥有各部分,部分与整体共存,如果整体不存在了,部分也会消失,这称之为组合。 class Car { Wheel ws[4]; Engine e[1]; // ... };
孤立的类只能描述实体集合的特征同一性,而客观世界中实体集合的划分通常还要考虑实体特征方面有关联的相似性。 如果将相似的事物用不同的类型来表示,能够表示其差别,但体现不了它们之间存在共性的事实,且共性的表示也可能不一致。当扩充维护过程中需要对其共性部分进行修改时,就面临着保持一致性的问题。 如果将相似的事物用相同的类型来表示,则体现其差别就十分困难,且失去了类型化的支持。一旦需要扩充和修改,将影响用此类型表示的所有事物。
方式1、重复定义共性来表示“is a” 方式2、-将共性表示为一种类型来表示“is a” 方式3、通过继承来表示“is a”
上面两张方式无论是那种方式:对于人来讲,虽然能表示出类之间的共性部分 – 但都无法告诉编译器或是其它工具Manager is also an Employee. 正确的方法是通过附加一点信息,显示地声明 Manager is an Employee: The Manager is derived(派生) from Employee, and conversely, Employee is a base class(基类) for Manager. 因为基类的成员被派生类所继承,所以继承有益于代码重用(code reuse)。 “has a”关系即组合关系,通过定义类的属性的方式实现的;“is a”关系即继承关系,通过类继承实现。 继承允许设计者在一个共同的基类中表达多个类的组合特征,例如交通工具就可以作为自行车、汽车等多个类的共同基类。
一个派生类不仅可以从一个基类派生,也可以从多个基类中派生。一个派生类有两个或多个基类的称为多个基类能够多重继承(multiple inheritance)。
关于基类和派生类的关系,可以表述为:派生类是基类的具体化,而基类则是派生类的抽象。 使用继承容易犯的错误:如果写了一个CMan类代表男人,后来又发现需要一个CWoman类来代表女人,仅仅因为CWoman类和CMan类有共同之处,就让CWoman类从CMan类派生而来,是不合理的。因为“一个女人也是一个男人”从逻辑上不成立。
基本概念与语法:class <类名>:<继承方式><基类名1>, <继承方式><基类名2>,... 构造一个派生类包括以下3部分工作 :
在设计时要根据派生类的需求慎重选择基类,使冗余量最小。 #include <iostream> using namespace std; class A { public: int a; int b; private: int c; protected: int d; }; class B: public A { int c; }; main( ) { cout << ” size of A is” << sizeof(A); cout << ” size of B is” << sizeof(B); }
输出: size of A is 16 派生类的存储结构与基类的存储结构存在着“粘接(splice)”关系:
只有公用派生类才是基类真正的子类型,它完整地继承了基类的功能。基类与派生类对象之间有赋值兼容关系,由于派生类中包含从基类继承的成员,因此可以将派生类的值赋给基类对象,在用到基类对象的时候可以用其派生类对象代替。赋值兼容存在以下三种形式:
可以用子类(即公用派生类)对象对其基类对象赋值,如:
如已定义了基类A对象a,可以定义a的引用变量:
当通过基类指针或引用操作时,派生类的对象可被当做基类的对象看待。 class Employee { public: string name; short department; // ... }; class Manager : public Employee { short level; // ... }; void f( Employee* pe ) {}; void main( ) { Employee e; Manager m; f( &e ); f( &m ); Employee *pe = &m;//基类对象指针指向派生类,派生类对象被当做基类对象看待了 pe -> department = 10; // OK pe -> level = 1; // error C2039: “level”: 不是“Employee”的成员 }
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论