5

I'm working on a physics simulation.

I have an ArrayList that holds all the objects in my simulation. I have a parent class: Shape, and two child classes: Circle and Rectangle.

The parent class, of course, doesn't have a draw() method but each of the child classes does. Therefore, when I'm looping trough the list to draw each element, it doesn't allow me because there isn't a draw() method in the Shape class (as I'm defining the list as ArrayList<Shape>, and adding each new element with a child class instance).

Is there a way to resolve this problem in a good and neat way?

Massimiliano Kraus
  • 3,638
  • 5
  • 27
  • 47
Robot0110
  • 191
  • 8

3 Answers3

4

it seems to provide an abstract method for the Shape class where all subclasses share a common behaviour is best for the task at hand.

Consider this is the Shape class:

public abstract class Shapes{
    public abstract void Draw();
}

the Rectangle class:

public class Rectangle extends Shapes{
    public void Draw(){
        System.out.println("Rectangle");
    }
}

the Circle class:

public class Circle extends Shapes{
    public void Draw(){
        System.out.println("Circle");
    }
}

now considering that both Circle and Rectangle are of type Shape, you can create objects of type Circle or/and Rectangle, add them to the ArrayList, iterate over it, and invoke the Draw() method on each object like so:

ArrayList<Shapes> shapes = new ArrayList<>();
shapes.add(new Circle());
shapes.add(new Rectangle());
shapes.forEach(Shapes::Draw);

result when Draw() method is invoked on each object:

Circle
Rectangle
Ousmane D.
  • 54,915
  • 8
  • 91
  • 126
4

The neatest way to move forward is to use interfaces.

public interface Shape {
    void draw();
}

public class Rectangle implements Shape {
    @Override
    public void draw() { // draw rect }
}

public class Circle implements Shape {
    @Override
    public void draw() { // draw circle }
}

If you want Shape to share some other logic with it's children you can create an AbstractShape class implementing Shape with any additional code and extend the child classes using this abstract class.

abhipil
  • 164
  • 2
  • 13
  • 2
    Since this interface declares only a `draw()` method, I would name the interface `Drawable`, instead of `Shape`. – AJNeufeld Apr 16 '17 at 20:02
  • @AJNeufeld yes that would be better. Conventionally interfaces should be names after adjectives. – abhipil Apr 16 '17 at 20:10
0

This is how I would do it.

A class called Shapes that has a field for List<Shape> Shape is an interface holding the method draw() getArea() or any others. Have as many classes implementing Shape, circle, rectangle, square etc.

sanodano
  • 11
  • 4