1. 继承的本质(目的)
简单来说就是为了代码的复用。
通常情况下,B(派生类)是A(基类)的一种,那么A所包含的属性和行为B也会有,如果对于同一问题A、B解决的办法一致,那么B可以直接使用A的行为方式,不需要自己也实现,直接复用;
如果A、B对于处理同一问题所使用的方式不同,那么B就需要重写从A继承下来的方法,因为对子类已经不适用。
2. 理解代理、组合以及继承思想
- 代理:被代理类的接口的功能子集。假设被代理类有10个借口,但是经过代理类包装,只向用户暴露5个接口,得到一个特定功能的类,比如STL中的容器适配器就是这样实现的;
- 组合:a part of。x是y的一部分,如脑袋是人的一部分,身份证号码是人信息的一部分等等;
- 继承:a kind of。x是y的一种,老师是职业的一种,运动鞋是鞋的一种,公交车是车的一种等等。
3. 基类和派生类对象内存的基本布局
class Base {
public:
int ma;
protected:
int mb;
private:
int mc;
};
class Derive :public Base {
public:
int ma;
protected:
int mb;
private:
int mc;
};
对象的内存布局:
4. 派生类继承了基类的那些内容?
派生类继承了除基类构造函数和析构函数以外的所有方法和数据,包括私有的成员方法和数据,即使不可见单依然存在于派生类对象的内存中,也包括基类的作用域。
如上图,基类和派生类可以存在同名的成员变量,不会引起冲突的原因是派生类继承了基类的作用域,如Base::ma,Base::mb
,因为是处于不同作用域的数据。
5. 派生类继承基类来的数据的访问权限
- 默认继承方式是private继承,和类的默认访问权限是一样的
class Derive :Base {
public:
int ma;
protected:
int mb;
private:
int mc;
};
- 继承方式分为3种,public、protected、private,不同继承方式下子类对于基类访问权限如下:
public继承方式: 实际开发中用的最多的
class Derive : public Base {
public:
int ma;
protected:
int mb;
private:
int mc;
};
基类中所有 public 成员在派生类中为 public 属性;
基类中所有 protected 成员在派生类中为 protected 属性;
基类中所有 private 成员在派生类中不能使用,是不可见的。
protected继承方式:
class Derive : protected Base {
public:
int ma;
protected:
int mb;
private:
int mc;
};
基类中的所有 public 成员在派生类中为 protected 属性,相当于放在派生类的protected 下;
基类中的所有 protected 成员在派生类中为 protected 属性,相当于放在派生类的protected 下;
基类中的所有 private 成员在派生类中不能使用,是不可见的。
private继承方式: 开发中几乎不可能用到的继承方式
class Derive : private Base {
public:
int ma;
protected:
int mb;
private:
int mc;
};
基类中的所有 public 成员在派生类中均为 private 属性,相当于放在派生类的private;
基类中的所有 protected 成员在派生类中均为 private 属性,相当于放在派生类的private;
基类中的所有 private 成员在派生类中不能使用,是不可见的。
总结:
基类中的访问权限不能大于继承方式的权限;
不论以任何方式继承,子类继承父类的私有的数据,子类永远是不能访问的(但是还是会继承到子类对象的内存中来);
外部只能访问public的成员
class定义的类,默认继承方式是private
struct定义的类,默认继承方式是public