Java 如何在OOP中实现图形层次结构
我对一些基本OOP概念的理解有问题。我将试着用一个例子来描述它。假设我有一个应用程序,它可以绘制不同形状的图形 我创建了一个Figure类并添加了一个字段Shape(这是一种枚举,可以是Shape.Circle或Shape.Square) 当我需要向应用程序添加更多形状时,我必须向draw()方法添加更多ifs。我觉得很糟糕 我可以使Figure类抽象(或使其成为接口),从该类继承具体形状的图形并重写draw()方法 当我需要新的形状时,我只需要添加新的类 接下来,我决定我的数字要有一种颜色:黑色还是白色。黑色正方形和白色正方形的绘制方式应不同。问题看起来是一样的。我可以在Figure类中添加颜色字段,并在每个draw方法中处理ifs,或者创建诸如BlackCircle、BlackSquare、WhiteCircle、WhiteSquare之类的类 后来,如果我决定为Figure添加另一个属性(比如大小可以是小的、中的或大的),我必须创建2*2*3类,比如BigBlackCircle、SmallWhiteSquare等等。我不能在运行时更改图形的颜色或形状。我认为这不是正确的方法 为了理解这个问题,我发现我仍然可以为所有数字设置一个单独的类。然后我将颜色、形状、大小存储为字段,并添加负责绘图的DisplayManager类。我可以为不同的绘图算法使用不同的DisplayManager实现Java 如何在OOP中实现图形层次结构,java,oop,Java,Oop,我对一些基本OOP概念的理解有问题。我将试着用一个例子来描述它。假设我有一个应用程序,它可以绘制不同形状的图形 我创建了一个Figure类并添加了一个字段Shape(这是一种枚举,可以是Shape.Circle或Shape.Square) 当我需要向应用程序添加更多形状时,我必须向draw()方法添加更多ifs。我觉得很糟糕 我可以使Figure类抽象(或使其成为接口),从该类继承具体形状的图形并重写draw()方法 当我需要新的形状时,我只需要添加新的类 接下来,我决定我的数字要有一种颜色:黑
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
}
}
但通过这种方式,我回到了步骤1中的问题:我必须在draw()方法中处理许多if。有人能解释一下这里的正确方法吗?我应该如何设计类以节省应用程序的灵活性?与其声明
DisplayManager.draw(Figure)
,不如声明Figure.draw(DisplayManager)
。为显示管理器实现一些方法,以便可以从图[drawPoint(),drawLine(),…]中使用
对于
Figure
的每个扩展,实现自己的绘图(DisplayManager)
,它使用给定的DisplayManager的特定实例amit所说的,并且您可以在Square类的draw()方法中处理绘制黑色或白色正方形的不同方式,使用if语句或类的其他属性
例如,可以使用color属性和另一个枚举属性,枚举绘制正方形的不同方法,并在draw()方法中处理它
例如,使用“大小”元素来显示一个概念:
public abstract class Figure {
public enum Size {
SMALL(10), MEDIUM(20), LARGE(30);
private int actualSize;
private Size(int actualSize) {
this.actualSize = actualSize;
}
public int getActualSize() {
return actualSize;
}
}
public int x,y;
public Size size = Size.MEDIUM;
public Color color = Color.BLACK;
public abstract void draw(DisplayManager displayManager);
}
public class Square extends Figure {
public enum Corners {
SHARP, ROUNDED
}
public Corners corners = Corners.SHARP;
@Override
public void draw(DisplayManager displayManager) {
int s = size.getActualSize();
displayManager.setColor(color);
switch (corners) {
case SHARP:
displayManager.drawBox(x-s, y-s, x+s, y+s);
break;
case ROUNDED:
displayManager.drawRoundedBox(x-s, y-s, x+s, y+s);
break;
}
}
}
(为节省空间而将属性公开,在适用的情况下将private与getter/setter一起使用,当然需要设置属性:)
在这里,枚举有两种工作方式——一种实际保存用于绘图的可用数据,另一种只是充当鉴别器。谢谢。我在GoF的设计模式中发现了几乎相同的解决方案。
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
}
}
public abstract class Figure {
public enum Size {
SMALL(10), MEDIUM(20), LARGE(30);
private int actualSize;
private Size(int actualSize) {
this.actualSize = actualSize;
}
public int getActualSize() {
return actualSize;
}
}
public int x,y;
public Size size = Size.MEDIUM;
public Color color = Color.BLACK;
public abstract void draw(DisplayManager displayManager);
}
public class Square extends Figure {
public enum Corners {
SHARP, ROUNDED
}
public Corners corners = Corners.SHARP;
@Override
public void draw(DisplayManager displayManager) {
int s = size.getActualSize();
displayManager.setColor(color);
switch (corners) {
case SHARP:
displayManager.drawBox(x-s, y-s, x+s, y+s);
break;
case ROUNDED:
displayManager.drawRoundedBox(x-s, y-s, x+s, y+s);
break;
}
}
}