面试题答案
一键面试实际场景
假设我们正在开发一个图形绘制系统,有不同类型的图形,如圆形、矩形、三角形等。我们希望通过一个统一的接口来绘制不同的图形,而不需要针对每种图形单独编写绘制代码,这时候就可以使用多态。
代码示例
#include <iostream>
#include <cmath>
// 基类图形
class Shape {
public:
virtual void draw() const = 0; // 纯虚函数,强制子类实现
};
// 圆形类,继承自Shape
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
void draw() const override {
std::cout << "Drawing a Circle with radius " << radius << std::endl;
}
};
// 矩形类,继承自Shape
class Rectangle : public Shape {
private:
double width;
double height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
void draw() const override {
std::cout << "Drawing a Rectangle with width " << width << " and height " << height << std::endl;
}
};
// 三角形类,继承自Shape
class Triangle : public Shape {
private:
double base;
double height;
public:
Triangle(double b, double h) : base(b), height(h) {}
void draw() const override {
std::cout << "Drawing a Triangle with base " << base << " and height " << height << std::endl;
}
};
// 绘制函数,接受Shape指针
void drawShape(const Shape* shape) {
shape->draw();
}
多态提高灵活性和可维护性的说明
- 灵活性:
- 当需要添加新的图形类型时,如梯形,只需要创建一个继承自
Shape
的Trapezoid
类,并实现draw
函数。而无需修改现有的绘制函数drawShape
。这使得系统很容易扩展,增加新的图形类型不会影响到其他已有的代码逻辑。 - 可以通过一个
Shape
指针或引用来操作不同类型的图形对象,在运行时根据实际对象类型调用相应的draw
函数,使得代码更加灵活,适应不同的需求。
- 当需要添加新的图形类型时,如梯形,只需要创建一个继承自
- 可维护性:
- 每个图形的绘制逻辑封装在各自的类中,当需要修改某种图形的绘制方式时,只需要修改对应类中的
draw
函数,而不会影响到其他图形类和绘制函数drawShape
。这样使得代码的维护更加简单,减少了修改一处代码导致其他地方出现问题的风险。 - 多态使得代码结构更加清晰,符合单一职责原则,每个类只负责自己的功能,提高了代码的可读性和可维护性。
- 每个图形的绘制逻辑封装在各自的类中,当需要修改某种图形的绘制方式时,只需要修改对应类中的
使用示例
int main() {
Circle circle(5.0);
Rectangle rectangle(4.0, 3.0);
Triangle triangle(4.0, 5.0);
drawShape(&circle);
drawShape(&rectangle);
drawShape(&triangle);
return 0;
}
上述代码在 main
函数中创建了不同类型的图形对象,并通过 drawShape
函数绘制它们,展示了多态的实际应用。