继承概念
面向对象程序设计有四个主要特点:抽象、封装、继承和多态。要较好的进行面向对象程序设计,还必须了解面向对象程序设计两个重要特征——继承和多态。
类之间的关系
包含关系,用以描述一个类由多个“部件类”组成。实现包含关系用类成员表示,即一个类中的数据成员是另一种已经定义的类。
使用关系,一个类部分地使用另一个类。通过类之间成员函数的互相联系,定义友元或者对象参数传递实现。
继承关系,关系具有传递性,不具有对称性。
子类拥有父类的所有成员变量和成员函数,还可以拥有父类没有的方法和属性。子类就是一种特殊的父类,子类对象可以当做父类对象使用。
派生类的访问控制
派生类继承了基类的全部成员变量和方法,但是这些成员的访问属性,在派生过程中时可控的。
单个类的访问控制
类成员访问级别(public,private,protected)
不同的继承方式会改变继承成员的访问属性
1)在C++中的继承方式会影响子类的对外访问属性。
public :父类成员在子类中保持原有访问级别。
private :父类成员在子类中变为private成员。
protected:父类中的public成员会变成protected。父类中的protected成员不变,父类中的private成员不变。
2)private成员在子类中依然存在,但是却无法访问到。不论哪种方式继承基类,派生类都不能直接使用基类的私有成员。
派生类类成员访问级别设置的原则
需要被外界访问的成员直接设置为public。
只能在当前类中访问的成员设置private。
只能在当前类和子类中访问的成员设置为protected,protected成员的访问权限介于public和private之间。
继承中的构造和析构
类型兼容原则
类型兼容原则是指在需要基类对象的任何地方,都可以使用共有派生类的对象来替代。通过公有继承,派生类得到了积累中出了构造函数、析构函数之外的所有成员。这样,公有派生类就具备了基类的所有功能,凡是基类能解决的问题,公有派生类都可以解决。
类型兼容原则中所指的替代包括以下情况:
1)子类对象可以当做父类对象使用。
2)子类对象可以直接赋值给父类对象。
3)子类对象可以直接初始化父类对象。
4)父类指针可以直接指向子类对象。
5)父类引用可以直接引用子类对象。
在替代之后,派生类对象就可以当做基类对象使用,但是只能使用从基类继承而来的成员。
类型兼容原则是多态的重要基础之一。
继承中的构造析构调用原则
子类对象在创建时会首先调用父类的构造函数,父类的构造函数执行结束后,执行子类的构造函数。如果父类的构造函数有参数,需要在子类的初始化列表当中显式调用。
析构函数的调用先后顺序与构造函数相反。
继承与组合混搭的情况下,构造和析构的调用原则
先构造父类,再构造成员变量,最后构造自己。
先析构字节,再析构成员变量,最后析构父类。
//子类对象如何初始化父类成员
//继承中的构造和析构
//继承和组合混搭情况下,构造函数、析构函数调用顺序研究
#include <iostream>
using namespace std;
class Object
{
public:
Object(const char* s)
{
cout<<"Object()"<<" "<<s<<endl;
}
~Object()
{
cout<<"~Object()"<<endl;
}
};
class Parent : public Object
{
public:
Parent(const char* s) : Object(s)
{
cout<<"Parent()"<<" "<<s<<endl;
}
~Parent()
{
cout<<"~Parent()"<<endl;
}
};
class Child : public Parent
{
protected:
Object o1;
Object o2;
public:
Child() : o2("o2"), o1("o1"), Parent("Parameter from Child!")
{
cout<<"Child()"<<endl;
}
~Child()
{
cout<<"~Child()"<<endl;
}
};
void run05()
{
Child child;
}
int main(int argc, char *argv[])
{
cout<<"demo05_extend_construct_destory.cpp"<<endl;
run05();
system("pause");
return 0;
}
继承中的同名成员变量处理方法
当子类成员变量与父类成员变量同名时,子类依然从父类继承同名成员。在子类中通过作用域分辨符(::)进行同名成员的区分。
在派生类中使用基类的同名成员,需要显式的使用类名限定符。同名成员存储在内存中的不同位置。
派生类中的static关键字
基类定义的静态成员,会被所有的派生类共享,根据静态成员自身的访问特性和派生类的继承方式,在类层次体系当中具有不同的访问性质。
派生类中访问静态成员,需要显式的使用类名限定符进行调用,或者通过对象访问。
多继承
概念
一个类有多个直接基类的继承关系称为多继承。
多继承的派生类构造和访问
多个基类的派生类构造函数可以用初始时调用基类构造函数初始化数据成员。
执行顺序与单继承构造函数的情况类似,多个直接基类构造函数执行顺序取决于定义派生类时指定的各个继承基类的顺序。
一个派生类对象拥有多个直接或者间接基类的成员。不同名成员访问不会出现二义性,如果不同的基类拥有同名成员,派生类对象访问时应该加以识别。
虚继承
如果一个派生类从多个基类派生,而这些基类又有一个共同的基类,则在对该基类中声明的名字进行访问时,可能会产生二义性。
如果在多条继承路径上有一个公共的基类,那么在继承路径的某处汇合点,这个公共基类就会在派生类的对象中产生多个基类子对象。
要让这个公共基类在派生类中只产生一个子对象,必须对这个基类声明为虚继承,使这个基类成为虚基类。