面试题答案
一键面试设计思路
- 定义基类
Shape
:包含通用的draw
方法,此方法在基类中可作为一个占位符,具体实现由子类完成。 - 定义子类
Circle
和Rectangle
:继承自Shape
基类,并根据自身需求重写draw
方法,使其能够接收颜色、线条粗细等参数并绘制相应图形。在 JavaScript 中没有传统意义上的方法重载,我们可以通过函数参数的不同组合来模拟。
JavaScript 代码实现
class Shape {
draw() {
throw new Error('draw method must be implemented by subclasses');
}
}
class Circle extends Shape {
draw(color, lineWidth, radius, x, y) {
console.log(`Drawing a circle at (${x}, ${y}) with radius ${radius}, color ${color}, and line width ${lineWidth}`);
}
}
class Rectangle extends Shape {
draw(color, lineWidth, width, height, x, y) {
console.log(`Drawing a rectangle at (${x}, ${y}) with width ${width}, height ${height}, color ${color}, and line width ${lineWidth}`);
}
}
可能遇到的问题及解决方案
问题:
- 参数判断复杂:由于是模拟方法重载,需要在函数内部手动检查参数的个数和类型,以确定执行何种逻辑。例如,若
Circle
的draw
方法传入参数个数不对,可能导致程序逻辑错误。 - 代码可读性差:大量的参数判断逻辑会使函数代码变得冗长和难以理解,降低代码的可读性和维护性。
解决方案:
- 参数校验函数:可以编写单独的参数校验函数,在
draw
方法内部调用,对传入的参数进行合法性检查。这样可以将参数校验逻辑分离出来,使draw
方法的核心绘制逻辑更清晰。 - 使用对象参数:使用一个对象来传递参数,而不是多个离散的参数。这样在函数内部可以更方便地检查所需参数是否存在,并且对象的属性名可以使参数的含义更明确。例如:
class Circle extends Shape {
draw(options) {
const {color, lineWidth, radius, x, y} = options;
console.log(`Drawing a circle at (${x}, ${y}) with radius ${radius}, color ${color}, and line width ${lineWidth}`);
}
}
这样在调用 draw
方法时,通过传递一个对象字面量,如 circle.draw({color: 'red', lineWidth: 2, radius: 5, x: 10, y: 10})
,可以提高代码的可读性和可维护性,同时减少参数顺序错误等问题。