一、纯虚函数、抽象类
virtual void fun() = 0;
只有函数的声明,没有函数的定义;
class T
{
virtual <类型>函数名(<参数列表>) = 0;
}
抽象类:带存虚函数,从一些类中提取出来的公有特性的类;函数无法自己实现;
class Shape
{
public:
virtual void darw() = 0 ;
};
class Line : public Shape // 所有的子类都 要实现纯虚函数
{
public:
virtual void darw()
{
// to do
}
};
class Circle : public Shape // 所有的子类都 要实现纯虚函数
{
public:
virtual void darw()
{
// to do
}
};
void DrawWind(Shape *shape)
{
shape->drwa();
}
Line li; Cirlce cir;
darw(Line)
DrawWind(&Line);
DrawWind(&cir);
子类中的函数原型必须与父类完全相同,如果子类中的返回类型不同,则编译错误,如果参数不同则发生隐藏;
抽象类:
不能实例化抽象类的对象;(不能访问成员)
抽象类一般作指针或是引用用!
不能做形参或是返回值; 传指针或是引用是可以的;
下面三种错误的写法:
Base fun();
void fun(Base b);
(Base)a;
抽象类可以函数变通成员函数。
二、接口类
只含有纯虚函数的类称为接口类!!
命名以I或是M开头
从各种类中抽象出一些共有的行为,形成一个抽象类!比如能飞的类MFlyable
class MFlyable : public Bird, public People, public Plane /// 赋值兼容的前提是公有继承,
{
}
M类与子类的关系是: CAN_DO关系
三、动态多态的原理与本质
单重继承
子类的虚函数表中,无覆盖时,父类的虚函数地址放在子类的虚函数地址前面,此时,可以直接访问基类的函数;
而有覆盖时,父类的虚函数地址被子类的虚函数地址覆盖!此时不能直接访问基类的被覆盖的函数,但可以间接访问 :基类名::fun();
多重继承
无覆盖时,哪个父类有虚函数就为其生成对应的一个虚函数表;子类的虚函数表放在第一个虚函数表里;
有覆盖时,所有虚函数表中,子类中实现覆盖的虚函数在相应的虚函数表中都被子类的虚函数地址覆盖!
四、bridge 模式
低耦合,高聚合
低耦合:少使用继承的关系;
高聚合:多使用聚合的关系;
继承机制:将抽象部分与实现部分固定在一 起,使得难以对抽象部分与实现部分独立地进行修改、扩充、重用;
声明与实现分离;