前言
正如继承一笔财产要比自己白手起家容易一样,通过继承派生出的类通常比设计新类要容易得多。下面是可以通过继承完成的一些工作:
1)可以在已有类的基础上添加功能。例如,对于数组类,可以添加数学运算.
2)可以给类添加数据。例如,对于字符串类,可以派生出一个类,并指定字符串显示颜色的数据成员.
3)可以修改类方法的行为。
当然,可以通过复制原始类代码,并对其进行修改来完成上述工作,但继承机制只需提供新特性,甚至不需要访问源代码就可以派生出类。
类之间的关系
1.包含关系: A类中的一个数据成员是B类。
2. User关系: A类部分使用B类。通过类之间的成员函数的相互关系。定义友元函数或者对象参数传递实现。
3. 继承关系: 具有传递性,不具有对称性。
继承的基础知识
a. 继承是类之间定义的一种重要的关系;
b. 一个B类继承A类或从A类派生B类,其中A类称为父类(基类),B类称为子类(派生类);
c. 用图说明单继承和多继承:
派生类的语法定义
class B:public A
{
}
a. :后面的被称为基类名表,基类名表的构成: 访问控制+基类名;
b. 访问控制表示派生类对基类的继承方式,使用关键字:
public : 公有继承;
private: 私有继承;
protected: 保护继承
注意:private 和 protected 的区别只有在基类派生的类才会表现出来。派生类的成员可以直接访问基类的保护成员,但不能直接访问基类的私有成员
继承关系只要写了:+基类名表,就已经确定了。
派生类的访问控制
派生类访问控制的结论
a. protected: 修饰的成员变量和成员函数是为了在家族中使用;
b. 项目开发中,一般使用的是public ;
c. 需要被外部访问的成员直接设置为public;
d. 只能在当前类被访问的成员设置为private;
e. 只能在当前类和子类中访问的成员设置为protected。
继承的重要说明
a. 子类拥有父类除了父类构造和析构函数,所有的成员函数和成员变量;派生类需要自己的构造函数,可以根据需要添加额外的数据成员和成员函数;派生类不能直接访问基类的私有成员,而必须通过基类方法进行访问。
有关派生类构造函数的要点如下:
1)首先创建基类对象
2)派生类构造函数应通过成员初始化列表将基类的信息传递给基类构造函数
3)派生类构造函数应初始化派生类新增的数据成员
注意:基类构造函数负责初始化继承的数据成员;派生类的构造函数主要用于初始化新增的数据成员;派生类构造函数总是调用一个基类构造函数。
b. 子类就是一种特殊的父类;
c. 子类对象可以当做父类的对象使用;
d. 子类可以拥有父类没有的方法和属性。
多态公有继承
希望同一个方法在派生 类和基类中的行为是不一样的,换句话说,方法的行为取决于调用该方法的对象。
实现多态公有继承:
1.在派生类中重新定义基类的方法;
2.使用虚方法。
公有继承产生的基类和派生类是一种is-a关系,派生类对象也是一种基类对象,因为基类对象可以执行的类方法操作,派生类对象也可以使用。
is-a关系是一种不可逆关系。
使用虚方法:
1. 对于同一种方法在不同类的不一样的行为,使用关键字virtual。(只定义在基类的类声明中)
2. 如果要在派生类中重新定义基类的方法(如果有这种需要),通常将基类方法声明为虚的。
这样,程序将根据对象类型而不是引用或者指针类型来选择方法版本。
3. 使用虚方法将产生两种方法版本:基类一个,派生类一个。
4. 如果方法是通过引用或者指针而不是对象调用的(对象调用:哪类对象就调用哪类方法版本),它将确定使用哪一种方法版本。
5. 如果没有使用关键字virtual,程序将根据引用类型或者指针类型选择方法;
6. 如果使用了关键字virtual,程序将根据引用或者指针指向的对象类型来选择方法。
总之,使用了虚方法后,不管是直接的类对象还是通过引用或指针间接指向的类对象来寻找对应的方法版本。
7. 派生类构造函数在初始化继承的基类私有数据时,采用的是成员初始化列表法;然后在构造函数体中初始化新增的数据项。
8. 在派生类方法中,标准技术是使用作用域解析运算符来调用基类方法。
(派生类方法版本调用基类方法版本时,表明版本归属哪一类)。非虚函数就不用了,公有的嘛。
9. 为何使用需析构函数???
如果析构函数不是虚的,则只调用对应于指针类型的析构函数;
如果析构函数是虚的,则调用相应对象类型的析构函数;使用虚析构函数可以保证正确的析构函数序列被调用。