一、继承的相关概念
继承是⼀种复⽤⼿段,在继承关系⾥子类继承父类的成员,由此达到复⽤的⽬的。通过继承定义一个类,继承是类型之间的关系建模,共享公有的东西,实现各自本质不同的东西。
二、三种访问限定符&继承关系
三、继承的重要说明
1.子类拥有父类的所有成员变量和成员函数
2.子类就是一种特殊的父类
3.子类对象可以当作父类对象使用
4.子类可以拥有父类没有的方法和属性
四.派生类(子类)的访问控制
1.如若是public继承,父类在子类中保持原有访问类别
2.如若是protect继承,父类的public变为protected,private依然是private,protected依然是protected
3.如若是private继承,父类在子类中都是private
五、实现一个简单的继承
class Parent//基类 { private: int a; public: void print() { cout << "a=" << a << endl; } }; class Child :public Parent//派生类,这里的public 可以也可以是private或者protected { private: int b; };
总结:
1.基类的私有成员在派生类中是不能被访问的,如果一些基类成员不想被基类对象直接访问,但需要在派生类中能访问,就定义为保护成员。可以看出保护成员限定符是因继承才出现的。
2. public继承是一个接口继承,保持is-a原则,每个父类可用的成员对子类也可用,因为每个子类对象也都是一个父类对象。
3. protetced/private继承是一个实现继承,基类的部分成员并未完全成为子类接口的一部分,是has-a原则,所以非特殊情况下不会使用这两种继承关系,在绝大多数的场景下使用的都是公有继承。
4.不管是哪种继承方式,在派生类内部都可以访问基类的公有成员和保护成员,但是基类的私有成员存在但是在子类中不可见(不能访问)。
5.使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显示的写出继承方式。
6.在实际运用中一般使用都是public继承,极少场景下才会使用protetced/private继承.
六、继承与转换
类型兼容性原则:在需要基类对象的任何地方都可以使用公有子类对象代替,通过公有继承派生类得到了基类出构造和析构外的所有成员
①子类对象可以当作父类对象使用
②子类对象可以直接赋值给父类对象(切割/切片)
③子类对象可以直接初始化父类对象
④父类指针/引用可以指向子类对象
⑤子类指针/引用不能指向父类对象(可以通过强制类型转换实现)
class Parent//基类 { private: int a; public: void print() { cout << "我是父类" << endl; } protected: }; class Child :public Parent { private: int c; public: protected: }; int main() { Child c1; Parent *p = NULL; p = &c1;//父类指针指向子类对象 p->print();//调用父类函数 Parent &n = c1;//子类引用初始化父类 n.print();//打印父类函数 system("pause"); return 0; }
七、问题
答:①在子类对象构造时,需要调用父类对象的构造函数对其继承来的成员进行初始化
②在子类对象析构时,需要调用父类析构函数对其继承得到对象成员进行清理
继承中构造和析构的调用原则:
①子类对象在创建时首先调用父类的构造函数
②父类构造函数执行结束后,执行子类构造函数
③当父类构造函数中有参数时,需要在子类的初始化列表中显示调用
④析构函数调用的顺序与构造函数相反
八、继承体系中的作⽤域
1、在继承体系中基类和派⽣类都有独⽴的作⽤域。
2、⼦类和⽗类中有同名成员,⼦类成员将屏蔽⽗类对成员的直接访问,这就构成了隐藏,又称为重定义。
3、在⼦类成员函数中,可以使⽤基类::基类成员访问。
4、注意在实际中在继承体系⾥⾯最好不要定义同名的成员。