继承:在原由 类的基础上,派生出新类,用来解决新的问题
组合:有一个,has a
继承:是一个,is a
上述选择用哪个,根据问题,倘若两者都能解决时,首选组合,相对简单
继承和派生是对同一问题的不同角度来看:
保持:保持已有类的特性而构造新类的过程称为继承
扩展:在已有类的基础上新增自己的特性而产生新类的过程称为派生
继承的目的:充分利用原来已经有的程序,它的设计和它的实现
充分利用原来已经有的类,在这个基础上,再去建立新的类
派生的目的:遇到新的问题,原有的类不能够完全适用,不能解决新的问题了
--------------------------------------------------------------------------------
经过继承后:派生对象包含:包含了从基类继承过来的成员,继承过来不加改变,原封不动就用的那些
还可以改造从基类继承过来的成员
新增成员
默认情况下,基类的构造函数和析构函数不被继承
C++11可以用using关键字继承积累的构造函数,只能初始化从基类继承的成员,语法形式:using B::B <-针对派生类新增成员很少或者是没有新增成员时使用
改造基类成员:在派生类中可以定义与基类成员同名的成员,这样基类同名成员就被覆盖了
--------------------------------------------------------------------------------------
不同继承方式主要体现在:派生类成员对基类成员访问权限
派生类对象对基类成员的访问权限
公有继承:基类的public,protected成员,访问属性在派生类中保持不变
派生类中的成员函数,可以访问基类中的public,protected成员
派生类对象,只能访问基类中的public成员
私有继承:基类的public和protected成员,都以private身份出现在派生类中
将基类的原由对外接口都封闭掉
派生类中的成员函数:可以访问基类中的public和protected成员
派生类对象:不能访问从基类继承的任何成员
以私有继承的方式,公有成员到了派生类中也成了私有的,在类外不能直接访问,派生类就要解决必要的这种访问接口问题,派生类要自己定义一些新的访问接口,在函数调用中调用基类继承过来的函数
保护继承:基类的public和protected成员到了派生类中,都成保护成员
派生类中的成员函数,可以直接访问基类中的public和protected成员
派生的对象,不能直接访问从基类继承的任何成员
保护类成员的特点和作用:对其所在类对象的模块来说,它与private性质相同,保护成员从类外去看它就像私有一样,是不可直接访问的
对于派生类成员函数来说,它与public成员的性质相同,是可以访问的
既实现了数据隐藏,又方便继承,实现代码重用
对于基类和派生类都是自己团队所写,可以使用保护类,否则,尽量少用保护类
-----------------------------------------------------------------------------------------
类型转换:
公有继承: 公有派生类对象可以被当做基类对象使用,反之不行
派生类的对象可以隐含转换为基类对象
派生类的对象可以初始化基类的引用,指针
派生类的指针可以隐含转换为基类的指针
不要重新定义继承而来的非虚函数:
class Base1 { public: void display()const {cout<<"Base1::display()"<<endl;} }
class Base2:publicBase1 {public: void display()const {cout<<"Base2::display()"<<endl;} }
class Derived::public Base2 {public: void display()const {cout<<"Base2::display()"<<endl;} }
void fun(Base1 *ptr) //参数为指向基类对象的指针
{ptr->display();} //对象指针->成员名
int main()
{Base1 base1;
Base2 base2;
Derived derived;
fun(&base1);//用Base1对象的指针调用fun函数
fun(&base2);//用Base2对象的指针调用fun函数
fun(&derived);//用Derived对象的指针调用fun函数
return 0;}
最后调用的都是base1,原因就是重定义继承而来的非虚函数。期望指针指向各自对象的时候,表现的不一样,但是达不到这个期望,要用虚函数。