面试题答案
一键面试继承导致代码耦合的原因
- 基类修改影响派生类:当基类的成员变量、成员函数的定义或接口发生改变时,所有继承自该基类的派生类都可能受到影响。例如,基类中一个成员函数的参数列表发生变化,那么派生类中重写该函数的地方都需要相应修改,这使得派生类与基类紧密耦合在一起。
- 派生类依赖基类实现:派生类在一定程度上依赖基类的实现细节。如果基类内部的实现逻辑改变,即使接口不变,派生类的行为也可能受到影响。比如基类的某个成员函数内部的算法改变,派生类如果依赖该函数的特定执行逻辑,就可能出现错误。
减轻耦合的常见方法
- 使用组合替代继承:组合是将一个类作为另一个类的成员变量。例如,有一个
Car
类,原本可能通过继承Engine
类来获取发动机相关功能,但可以改为在Car
类中包含一个Engine
类型的成员变量。这样Car
类对Engine
类的依赖更加松散,Engine
类的修改对Car
类的影响更小。示例代码如下:
class Engine {
public:
void start() {
// 发动机启动逻辑
}
};
class Car {
private:
Engine engine;
public:
void startCar() {
engine.start();
}
};
- 依赖抽象(接口继承):通过定义抽象基类(含有纯虚函数)或接口类,派生类只依赖于抽象的接口而不是具体的实现。派生类只需实现这些抽象接口,基类实现的改变不会直接影响到派生类。例如:
class Drawable {
public:
virtual void draw() = 0;
};
class Circle : public Drawable {
public:
void draw() override {
// 绘制圆形的逻辑
}
};
class Rectangle : public Drawable {
public:
void draw() override {
// 绘制矩形的逻辑
}
};
这样Circle
和Rectangle
类只依赖于Drawable
抽象类的接口,Drawable
抽象类内部实现的改变不会直接影响到它们。