我对一些基本的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()方法添加更多ifs。我认为这很糟糕。
我可以使Figure类抽象化(或使其成为一个接口),从此类继承具体形状的图形并重写draw()方法。
public abstract Figure { void draw(); }
public class Circle extends Figure {
@Override public void draw() {
// draw a circle
}
}
// same for Square
当我需要新形状时,只需添加新类。
接下来,我决定要为图形添加颜色:黑色或白色。黑色正方形和白色正方形应以不同的方式绘制。问题看起来一样。我可以将颜色字段添加到Figure类中,并在每个draw方法中处理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()方法中处理很多ifs。有人可以在这里解释正确的方法吗?我应该如何设计类以节省应用程序的灵活性?
最佳答案
而不是声明DisplayManager.draw(Figure)
,而是声明Figure.draw(DisplayManager)
。为DisplayManager
实现一些方法,以便可以从Figure
[drawPoint(),drawLine(),....]使用它
对于Figure
的每个扩展,实现自己的draw(DisplayManager)
,该DisplayManager
使用给定的特定实例
关于java - 如何在OOP中实现数字层次结构,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9149848/