简体   繁体   中英

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 ; I have 3 types, Rectangle , Circle and Figure . All of them extend 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() ; and getStartY() ; and I can't, I only can access the methods that are on Figures also.

Your abstract class should define the getStartX and getStartY method. Either abstract if you want Rectangle , Circle and Figure to have a different behaviour and force them to Override those methods. Else just put the method in Figures it'll be available for use (with the appropriate keyword : public / protected depending your needs).

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:

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

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. 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.

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:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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