我在理解一些基本的 OOP 概念时遇到问题。我将尝试用一个例子来描述它。假设我有一个应用程序应该绘制不同形状的图形。
我创建一个Figure类并添加一个Shape字段(这是一种枚举,可以是Shape.Circle或Shape.Square)。
public class Figure {
public Shape shape;
public void draw() {
if( shape == Shape.Square )
// draw a square
else if( shape == Shape.Circle )
// draw a circle
}
}
当我需要向应用程序添加更多形状时,我必须向 draw() 方法添加更多 if。我觉得这样不好。
我可以使Figure类抽象(或使其成为一个接口(interface)),从此类继承具体形状的图形并重写draw()方法。
public abstract Figure { void draw(); }
public class Circle extends Figure {
@Override public void draw() {
// draw a circle
}
}
// same for Square
当我需要新形状时,我只需添加新类。
接下来我决定为我的人物选择一种颜色:黑色或白色。黑色方 block 和白色方 block 应该不同地绘制。问题看起来是一样的。我可以向 Figure 类添加颜色字段,并在每个绘制方法中处理 ifs,或者创建 BlackCircle、BlackSquare、WhiteCircle、WhiteSquare 等类。
稍后,如果我决定为 Figure 添加另一个属性(比如说 Size,可以是 Small、Medium 或 Large),我必须创建 2 * 2 * 3 类,如 BigBlackCircle、SmallWhiteSquare 等。我无法在运行时更改图形的颜色或形状。我认为这不是正确的方法。
试图理解这个问题,我发现我仍然可以为所有图形设置一个类。然后我将颜色、形状、大小存储为字段,并添加负责绘图的 DisplayManager 类。我可以针对不同的绘图算法使用不同的 DisplayManager 实现。
public class Figure {
public Shape shape;
public Color color;
public Size size;
public DisplayManager display;
public void draw() {
display.draw(this);
}
}
public class DisplayManager {
public void draw( Figure figure ) {
// drawing based on figure's shape, color and size
}
}
但是这样我又回到了第一步的问题:我必须在draw()方法中处理很多if。有人可以在这里解释一下正确的方法吗?我应该如何设计类以保持应用程序的灵活性?
最佳答案
不要声明 DisplayManager.draw(Figure)
,而是声明 Figure.draw(DisplayManager)
。为 DisplayManager
实现一些方法,以便可以从 Figure
[drawPoint()、drawLine(),....]
对于 Figure
的每个扩展,实现其自己的 draw(DisplayManager)
,它使用给定 DisplayManager
的特定实例
关于java - 如何在 OOP 中实现图形层次结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9149848/