我对一些基本的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/

10-13 04:41