不同类型的访问方法

Access methods on different types

我有这样的东西:

Figures fig = new Line(); 

在哪条线上延伸图。图是一个抽象 class,只有一个方法 getType() 通过返回 String 告诉我它是哪个图; 我有 3 种类型,RectangleCircleFigure。他们都扩展了 Figures.

现在是真正的问题。我将每一个都存储在 List<Figures> 中,我想访问每个对象的某些方法,例如 getStartX();和 getStartY();而且我不能,我也只能访问 Figures 上的方法。

您的摘要 class 应该定义 getStartXgetStartY 方法。如果您希望 RectangleCircleFigure 具有不同的行为并强制它们使用 Override 这些方法,则可以抽象。否则只需将方法放在 Figures 中即可使用(使用适当的关键字:public/protected,具体取决于您的需要)。

如果您想使用特定于 class 的方法,您需要检查它是哪个实例。像

for (Figures figure: myList) {
  int x = figure.getStartX(); // Method common and declared in Figures  
  if (figure instanceof Circle) {
    System.out.println("Oh no a Circle!");
    int radius = ((Circle)figure).getRadius();
    ...
  }
}

对于您的 Rectangle/Line,您可以使用 2 种方法定义接口:

public interface HasEndpoints {
  int getEndX();
  int getEndY();
}

public class Rectangle implements HasEndpoints {
   ...
   public int getEndX() {return endx;}
   ...
}

for (Figures figure: myList) {
  int x = figure.getStartX(); // Method common and declared in Figures  
  if (figure instanceof HasEndpoints) { // Rectangle and Line will go there
    System.out.println("HasEndpoints implementor");
    int endX = ((HasEndpoints)figure).getEndX();
    ...
  }
}

您可以将 instanceofif...else 一起使用并动态投射您的对象

Figure fig = new //Circle()/Triangle()/Rectangle();

if( fig instanceof Circle) {
   ((Circle) fig).getRadius(); //This method is only available in Circle class
}

getStartX()getStartY() 应该在 Figure class 中声明,或者您需要将对象转换为 Line class:

Figure figure = figures.get(0);
if ("line".equals(figure.getType())) {
   Line line = (Line)figure;
}

另一种选择是使用反射。但是您仍然需要确定,请求的方法可以被调用。

您总是可以将图形转换为线,但不是最佳选择。根据问题,您可以应用 Visitor Pattern 或将这些方法添加到 Figure,即使 Circle 没有起点和终点。

例如

public abstract class Figure{
    public abstract void visit(FigureVisitor visitor);
}

public class Line extends Figure{
    public void visit(FigureVisitor visitor){
        visitor.visitLine(this);
    }
}

public interface FigureVisitor{
    public void visitLine(Line figure);
    public void visitCircle(Circle figure);
}

public class StartingPointsVisitor implements FigureVisitor{
    private Double startX;
    private Double startY;
    private Double endX;
    private Double endY;

    public void visitLine(Line figure){
        this.startX = figure.getStartX(); //No cast needed
        ...
    }
    public void visitCircle(Circle figure){
        //Stub-method
    }

    //Getters to read the results
}

是一个更复杂的解决方案,但正如我所说,这取决于问题,并且大部分复杂性仍然存在于 Visitor