继承和多态

来源:互联网 发布:抱枕材料 知乎 编辑:程序博客网 时间:2024/06/08 10:53

一.继承


       1.定义:继承是面向对象复用的重要手段,是类型之间的关系建模,共享共有的东西,实现各自本质不同的东西。
       三种继承关系下基类成员在派生类发生的访问关系变化:

例:
#include<iostream>#include<string>using namespace std;class Person {public:     Person() : _name("sssss"){}     void Display()      { cout << _name << endl; } protected:   string _name;   // 姓名 };class Student : public Person {protected:     int _num;   // 学号 };int main(){Student s;cout << sizeof(s) << endl;s.Display();return 0;}
总结:
1. 基类的私有成员在派生类中是不能被访问的,如果一些基类成员不想被基类对象直接访问,但需要在派生类中能访问,就定义为保 护成员。可以看出保护成员限定符是因继承     才出现的。 
2. public继承是一个接口继承,保持is-a原则,每个父类可用的成员对子类也可用,因为每个子类对象也都是一个父类对象。 
3. protetced/private继承是一个实现继承,基类的部分成员并未完全成为子类接口的一部分,是 has-a 的关系原则,所以非特殊情 况下不会使用这两种继承关系,在绝大多数的     场景下使用的都是公有继承。
4. 不管是哪种继承方式,在派生类内部都可以访问基类的公有成员和保护成员,但是基类的私有成员存在但是在子类中不可见(不能 访问)。 
5. 使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显示的写出继承方式。 
6. 在实际运用中一般使用都是public继承,极少场景下才会使用protetced/private继承.
2. 赋值兼容规则
  1. 子类对象可以赋值给父类对象(切割/切片) 
  2. 父类对象不能赋值给子类对象 
  3. 父类的指针/引用可以指向子类对象 
  4. 子类的指针/引用不能指向父类对象(可以通过强制类型转换完成)
class A{public:int _a;};class B :public A{int _b;};int main(){A a;a._a = 1;B b;b._a = 2;//b._b = 3;    //子->父(对象,指针,引用)——切割a = b;A* p1 = &b;A& r1 = b;return 0;
3. 继承体系中的作用域
    1. 在继承体系中基类和派生类都有独立的作用域。 
    2. 子类和父类中有同名成员,子类成员将屏蔽父类对成员的直接访问。(在子类成员函数中,可以使用 基类::基类成员 访问)--隐藏 --重定义 
    3. 注意在实际中在继承体系里面最好不要定义同名的成员。
class A{public:int _a;};class B :public A{public:int _a;int _b;};//隐藏/重定义int main(){B b;b._a = 10;b.A::_a = 20;
当子类的成员与父类重名时,子类会隐藏父类。
重载:在同一个作用域中,函数名相同,参数列表不同
隐藏:子类和父类中有同名成员,子类成员将屏蔽父类对成员的直接访问。(在子类成员函数中,可以使用基类::基类成员 访问)
4. 继承分为单继承,多继承和菱形继承
    单继承:只有一个直接父类
    多继承:有两个或两个以上直接父类
    菱形继承存在二义性和数据冗余
虚继承能解决菱形继承的二义性和数据冗余
class A{public:int _a;};class B :public A{public:int _b;};class C :public A{public:int _c;};class D :public B, public C{public:int _d;};//对象模型:内存当中的分布int main(){D d;d.B::_a = 1;d.C::_a = 2;d._b = 3;d._c = 4;d._d = 5;}