【问题标题】:Access methods on different types不同类型的访问方法
【发布时间】:2015-05-13 14:07:50
【问题描述】:

我有这样的事情:

Figures fig = new Line(); 

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

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

【问题讨论】:

  • getStartX()getStartY() 方法是否存在于 RectangleCircle 类中?
  • 是的,但我想访问与这 3 不同的其他方法,例如 getradius();仅在 Circle 内...

标签: java android inheritance methods


【解决方案1】:

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

如果您想使用特定于某个类的方法,您需要检查它是哪个实例。类似的东西

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();
    ...
  }
}

【讨论】:

  • 但问题是我还有其他 3 种方法,我也必须具有与所有类(矩形/圆/线)不同的访问权限
  • 像 getRadius(on Circle) 和 getEndX 和 getEndY(on Line/Rectangle)
  • 更新了答案。您可能应该为 Line 和 Rectangle 获得一个额外的公共父级,或者使用像 (HasEndPoints) 这样的接口来定义您的 2 个方法。
  • getStartX() 不能存在于Figure 中,因为CircleFigure
  • @Ian2thedv 我不明白你的意思。如果getStartX()FiguresCircle 中定义在某个点扩展Figures 那么它是可访问的...
【解决方案2】:

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

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

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

【讨论】:

  • 谢谢!这确实有效!但稍作改动,我只使用 ((Circle) fig).getRadius();因为我的抽象类已经告诉我类型^^非常感谢!!!
  • 很高兴,因为您似乎是 StackOverflow 上的新手,别忘了将您的问题标记为已解决。
【解决方案3】:

您始终可以将 Figure 转换为 Line,但不是最佳选择。根据问题,您可以应用 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中

【讨论】:

    【解决方案4】:

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

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

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

    【讨论】:

    • 如果Figure fig = new Circle(),您希望getStartX() 的输出是什么?
    • @Ian2thedv 请阅读我的回答:either 该方法在 Figure 类中声明(返回 Circle,实施者必须知道,而不是我 - 它可以抛出 UnsupportedOperationException 例如。)使用强制转换。
    • 您在回答中没有提及有关 UnsupportedOperationException 的任何内容。
    • @Ian2thedv 因为它没有任何区别
    猜你喜欢
    • 2014-07-09
    • 1970-01-01
    • 1970-01-01
    • 2013-04-24
    • 2020-10-17
    • 1970-01-01
    • 2016-05-01
    • 2012-06-03
    • 1970-01-01
    相关资源
    最近更新 更多