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