面试题答案
一键面试对代码可维护性产生的主要影响
- 提高代码复用性:通过继承,子类可以复用父类的属性和方法,减少重复代码。当父类的代码发生修改时,只要接口不变,所有子类都能自动受益,降低维护成本。例如,有一个
Shape
父类,包含计算面积的基本方法框架,Circle
和Rectangle
等子类继承自Shape
,复用计算面积的方法框架,当修改计算面积的算法时,只需在Shape
类中修改,子类无需改动。 - 增强代码扩展性:容易添加新的子类。当有新的需求,需要创建新的类型时,可以基于现有的父类快速创建子类,并根据需要重写或扩展方法。例如,在图形绘制系统中,如果新增
Triangle
类,只需继承Shape
类,重写计算面积等相关方法即可,对已有代码影响小。 - 可能带来复杂性:继承层次过深可能导致代码理解和维护困难。因为子类不仅有自己的代码,还依赖父类代码,追踪代码逻辑时需要在多个类之间跳转。例如,一个继承体系有5 - 6层,从最底层子类追溯功能来源时会变得复杂。
- 破坏封装性风险:如果使用不当,继承可能破坏父类的封装性。子类可以访问父类的非私有成员,这可能导致父类内部实现细节暴露给子类,当父类实现改变时,可能影响子类。比如父类原本的一个实现细节被子类依赖,父类修改此细节后,子类可能出错。
举例说明
#include <iostream>
// 父类
class Shape {
public:
virtual double getArea() const {
return 0.0;
}
};
// 子类Circle
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
double getArea() const override {
return 3.14159 * radius * radius;
}
};
// 子类Rectangle
class Rectangle : public Shape {
private:
double width;
double height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
double getArea() const override {
return width * height;
}
};
int main() {
Circle c(5.0);
Rectangle r(4.0, 6.0);
std::cout << "Circle area: " << c.getArea() << std::endl;
std::cout << "Rectangle area: " << r.getArea() << std::endl;
return 0;
}
在这个例子中,Circle
和Rectangle
继承自Shape
类,复用了Shape
类中关于获取面积的方法框架。如果要修改计算面积的通用逻辑(例如添加一些通用的面积计算修正逻辑),只需要在Shape
类中修改getArea
方法,Circle
和Rectangle
子类会自动应用新逻辑,提高了代码可维护性。