面向对象的复用
-
拷贝、粘贴、修改
-
黑盒复用:
是一种功能复用,不需要被复用类的完整源实现代码。
水平关系-普通关联、聚合、组合、依赖
- 白盒复用:垂直关系-继承
是一种代码复用
继承的语法
格式:
class 派生类名: 继承方式 基类名称, (继承列表)
{
......
}
- 若不写继承方式,则默认为private继承
- 基类:被继承的类
- 派生类:继承基类的类,派生类可以继续派生
- 父类、子类:
在public继承下,称基类为父类,派生类为子类。 - 基类中的构造函数、析构函数、拷贝函数、赋值函数、自动转换函数不会被派生类自动继承。
继承的存储方式
B类继承A类
则B类的储存情况为
派生类中成员的访问控制
各继承方式下各类成员的访问情况变化
image.png派生类的构造和析构
- 基类的构造、析构:先基类,再派生类
- 派生类的构造函数:
构造顺序表中可以指定基类的构造函数或拷贝构造函数
多重继承时,基类按先后顺序构造 - 派生类的析构函数:
先执行派生类的析构,再自动执行基类析构
派生类中的成员函数
- newdefine
- redefine
- overload
- overwrite
派生类中定义了某个函数,且基类中有同名的函数,则派生类的函数会将基类的同名函数隐藏(hide)掉。
例子:
class A
{
public:
void F();
void F(int n);
void G();
virtual void H();
private:
void K();
int data;
};
class B:public A
{
public:
void BF(){} //newdefine的函数
void G(){} //redefine了基类的G()
void F(int n, int m) //定义了与基类同名的函数F,于是overwrite了基类的F
{
F(); //故此时overload基类的F,以下均非法,F都被hide
F(n);
}
}
复用方式的选择
- 功能复用较代码复用更好
- public继承能实现某种方便之处
class Car
{...};
class MTCar : public Car
{...};
class ATCar : public Car
{...};
class My{
public:
My(Car&c) //此中的Car类可以是MTCar对象,也可以是ATCar对象或Car
{pCar=&c;}
void Func(Car & c)
{c.Run();}
private:
Car * pCar;
};
int main()
{
Car car;
MTCar mtcar;
ATCar atcar;
My mycar(atcar);
mycar.Func(mtcar);
...
}
继承表示的逻辑关系
- public继承:
“is a”或“is a kind of”关系
子类是具有父类的所有行为,并加以细化。继承使用最多的便是public继承方式。
- private继承:
- protected继承:
意义不大
组合和继承的选择
优先选择组合,而不是继承
在需要派生新的子类的情况下,才应采用公有继承
网友评论