2

I have to solve this "container problem" in Java. I have an array made up with different figures and I'd like the following code to work:

 package container;
    class Figure{
        public void draw() {}
        public String getColor() { return null; }
    }

    class Square extends Figure{
        @Override
        public void draw(){
            System.out.println("Square");
        }
    }

    class Circle extends Figure{
        @Override
        public void draw(){
            System.out.println("Circle");
        }
        public float getRadius(){
            return 8;
        }
    }

    public class Container {

        public static void main(String[] args) {

            Figure[] figures = new Figure[3];
            figures[0]= new Circle();
            figures[1]= new Circle();
            figures[2]= new Square();

            for(Figure figure:figures){
                figure.getColor();
                figure.draw(); 
                ((Circle) figure).getRadius();          
            }        
    }
}

Where you can see there is a problem because Square hasn't got a getRadius() method. I have the following restrictions:

  • can't use generics
  • can't use instanceof

It should be a nice object-oriented design solution.

1
  • What is the expected behavior? Square is not a circle - how it's that line supposed to work? Commented Aug 6, 2015 at 12:27

4 Answers 4

1

Why don't you add an enum FigureType to your base class that identifies the child class?

public static enum FigureType {

    Square,
    Circle
}

public static class Figure {
    private FigureType type;

    public Figure(FigureType type) {
        this.type = type;
    }

    public FigureType getType() {
        return type;
    }

    public void draw() {
    }

    public String getColor() {
        return null;
    }
}

You would have to add a default constructor to each child class that calls the parent class constructor with its FigureType.

public static class Square extends Figure {

    public Square() {
        super(FigureType.Square);
    }

    @Override
    public void draw() {
        System.out.println("Square");
    }
}

public static class Circle extends Figure {

    public Circle() {
        super(FigureType.Circle);
    }

    @Override
    public void draw() {
        System.out.println("Circle");
    }

    public float getRadius() {
        return 8;
    }
}

Usage:

public static void main(String[] args) {

    Figure[] figures = new Figure[3];
    figures[0] = new Circle();
    figures[1] = new Circle();
    figures[2] = new Square();

    for (Figure figure : figures) {
        figure.getColor();
        figure.draw();
        if (figure.getType() == FigureType.Circle) {
            ((Circle) figure).getRadius();
        }
    }
}

Results:

Circle
Circle
Square

No exception

Sign up to request clarification or add additional context in comments.

Comments

1

How about adding getRadius to Figure, and then throw an UnsupportedOperationException in the implementation of square?

Comments

0

You want to write code that works for all types of Figures and you want different behavior if the Figure is a Circle or Square. This is why they invented polymorphism. Your code looks like:

Figure f;
if (f is Circle) {
  doFoo();
} else {
  doBar();
}

Instead the better way to do this is as follows:

interface Figure {
  public void do();
}

class Circle implements Figure {
  public void do() {
    doFoo();
  }
}

class Square implements Figure {
  public void do() {
    doBar();
  }
}

Then your code becomes:

Figure f;
f.do();

3 Comments

it's right but what if circle has got some behaviour (getRadious) that it's not present in square and figure?
Then don't expose it to the user. Why does the user need the radius.
The user is probably trying to perform some operation related to Figures and this operation I call do.
0

If you can't use the instanceof you can declare abstract method in the Figure class and add dummy implementation for figures that doesn't need it. The following code without instanceof and java generics works:

package container;

abstract class Figure {
    public void draw(){};
    public String getColor(){return null;};

    protected abstract float getRadius();
}

class Square extends Figure{
    @Override
    public void draw(){
        System.out.println("Square");
    }

    // zero radius for non-circle figures, for instance
    // or you can throw UnsupportedOperationException here.
    public float getRadius() { return 0;} 
}

class Circle extends Figure{
    @Override
    public void draw(){
        System.out.println("Circle");
    }
    public float getRadius(){
        return 8;
    }
}

public class Container {

    public static void main(String[] args) {

        Figure[] figures = new Figure[3];
        figures[0]= new Circle();
        figures[1]= new Circle();
        figures[2]= new Square();

        for(Figure figure:figures){
            figure.getColor();
            figure.draw(); 

            figure.getRadius();
        }        
    }
}

1 Comment

I know that would perfect but I was given the restriction "can't use instanceof"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.