Home > Back-end >  Java Create class instance based on user input
Java Create class instance based on user input

Time:11-08

I have some class Shape.

public abstract class Shape {
    String shapeColor;
    public Shape(String shapeColor){
        this.shapeColor = shapeColor;
    }

    abstract public double calcArea();
    @Override
    public String toString() { return "Shape"; }
    public String getShapeColor() { return shapeColor; }
}

Also, I have classes that extend from Shape: Triangle, Rectangle and Circle.

public class Triangle extends Shape {
    double a, h;

    public Triangle(String shapeColor, double a, double h) {
        super(shapeColor);
        this.a = a;
        this.h = h;
    }

    @Override
    public double calcArea() {return a * h / 2;}

    @Override
    public String toString() {
        return "Triangle";
    }
}
public class Rectangle extends Shape {
    double a, b;
    public Rectangle(String shapeColor, double a, double b) {
        super(shapeColor);
        this.a = a;
        this.b = b;
    }

    @Override
    public double calcArea() {
        return a * b;
    }

    @Override
    public String toString() {
        return "Rectangle";
    }
}
public class Circle extends Shape {
    double r;

    public Circle(String shapeColor, double r) {
        super(shapeColor);
        this.r = r;
    }

    @Override
    public double calcArea() {
        return (Math.PI * r * r);
    }

    @Override
    public String toString() {
        return "Circle"; 
    }
}

I want to create Arraylist<Shape> shapes and add shapes to it based on user input. So, I want to have something like

String[] userInput = scanner.nextLine().split(", ");
Shape shape = createNewShape(userinput)

For example:

"Circle, Blue, 7" -> Shape shape = new Circle("Blue", 7)

"Rectangle, Red, 5, 10" -> Shape shape = new Rectangle("Red", 5, 10)

But I want this to work even if new class that extends from Shape is created. For example if I will have new Shape Cube I will not have need to add something to my code:

"Cube, Red, 9" -> Shape shape = new Cube("Red", 9)

This question is close to what I need, but my classes have different amount of parameters. Maybe someone can give me a piece of advice how to make it work for different amount of parameters.

CodePudding user response:

You can search for Constructors on a specific package. For example, put all your shapes together in a x-named package and call Class.forName to get them.

public static void main(String[] args) {
    List<Shape> shapes = new ArrayList<>();

    shapes.add(create("Triangle", "Orange", 5, 6));
    shapes.add(create("Circle", "Blue", 7));
    shapes.add(create("Rectangle", "Red", 5, 10));

    shapes.forEach(System.out::println);
}

private static Shape create(String constructor, Object... objects) {
    try {
        final Constructor<?> _constructor = Class.forName("com.shapes."   constructor).getConstructors()[0];
        return (Shape) _constructor.newInstance(objects);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

My structure:

 com.mainPackage
    main.java
 com.shapes
    Shape.java
    Triangle.java
    Rectangle.java
    Circle.java
  •  Tags:  
  • java
  • Related