简体   繁体   English

不同类型的访问方法

[英]Access methods on different types

I have something like this:我有这样的事情:

Figures fig = new Line(); 

on which Line extends Figure.在哪条线上延伸图。 Figure is an abstract class that only has a method getType() that tells me which figure it is by returning a String ; Figure 是一个抽象类,它只有一个getType()方法,它通过返回一个String来告诉我它是哪个图形; I have 3 types, Rectangle , Circle and Figure .我有 3 种类型, RectangleCircleFigure All of them extend Figures .所有这些都扩展了Figures

Now the real question.现在是真正的问题。 I store every single one inside of a List<Figures> and I want to get access to some methods on each object like getStartX() ;我将每一个都存储在List<Figures>并且我想访问每个对象上的某些方法,例如getStartX() and getStartY() ;getStartY() ; and I can't, I only can access the methods that are on Figures also.我不能,我也只能访问Figures上的方法。

Your abstract class should define the getStartX and getStartY method.您的抽象类应该定义getStartXgetStartY方法。 Either abstract if you want Rectangle , Circle and Figure to have a different behaviour and force them to Override those methods.如果您希望RectangleCircleFigure具有不同的行为并强制它们Override这些方法,请使用抽象。 Else just put the method in Figures it'll be available for use (with the appropriate keyword : public / protected depending your needs).否则只需将方法放入Figures即可使用(使用适当的关键字: public / protected取决于您的需要)。

If you want to use methods that are specific to a class you'll need to check of which instance it is.如果要使用特定于类的方法,则需要检查它是哪个实例。 Something like就像是

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

For your Rectangle/Line you can define an interface with your 2 methods:对于您的 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();
    ...
  }
}

You can use instanceof with if...else and cast dynamically your object您可以将instanceofif...else并动态转换您的对象

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

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

You can always cast the Figure to Line, but not the best choice.您始终可以将 Figure 转换为 Line,但不是最佳选择。 Depending on the problem, you can apply Visitor Pattern or add those methods to Figure, even when the Circle doesn't have a starting and ending point.根据问题,您可以应用访问者模式或将这些方法添加到 Figure,即使 Circle 没有起点和终点。

For example例如

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
}

Is a more complex solution, but as i said, it depends on the problem, and most of the complex remains in the Visitor是一个更复杂的解决方案,但正如我所说,这取决于问题,并且大部分复杂的问题都保留在访问者中

Either getStartX() and getStartY() should be declared in Figure class or you need to cast the object to Line class: getStartX()getStartY()应该在Figure类中声明,或者您需要将对象强制转换为Line类:

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

Another option is to use reflection.另一种选择是使用反射。 But you still need to be sure, that the requested method can be called.但是您仍然需要确保可以调用请求的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM