I'm java newbie, currently working on this internship task:
Given the figure objects of the following types: square, triangle, circle, trapezium. Each shape can be drawn, get its area and color. Also, the figures have unique methods, for example: return the radius, the length of the hypotenuse, the length of the side, etc.
We need to generate a random set of shapes, the number of objects in the set is also not known in advance.
After generating the array, you need to display the entire list of objects that we have, for example:
Drawing triangle, area: 8.56, hypotenuse: 6.20, color: red
Drawing square, area: 27.27, side length: 5.22, color: blue
... and so on. It is necessary to describe the task using the principles of OOP.
What I need is general advices to make my code cleaner and better, and also some help with random array part. Here is the code I currently wrote:
Shape interface:
public interface Shape {
void draw();
double getArea();
ColorEnum getColor();
}
ColorEnum enum class:
public enum ColorEnum {
RED,
ORANGE,
YELLOW,
GREEN,
BLUE,
INDIGO,
VIOLET
}
Square class:
import java.awt.*;
public class Square implements Shape {
private double side;
private Color color;
public Square(Color color, double side) {
this.color = color;
this.side = side;
}
#Override
public void draw() {
System.out.println("Drawing square, area: " + String.format("%.2f", getArea()) + ", side length: " + String.format("%.2f", getSide()) + ", color: " + getColor());
}
#Override
public double getArea() {
return side * side;
}
#Override
public Color getColor() {
return color;
}
public double getSide() {
return side;
}
}
Triangle class:
public class Triangle implements Shape {
private double side1, side2, side3;
private ColorEnum color;
public Triangle(ColorEnum color, double side1, double side2, double side3) {
this.color = color;
this.side1 = side1;
this.side2 = side2;
this.side3 = side3;
}
#Override
public void draw() {
System.out.println("Drawing triangle, area: " + String.format("%.2f", getArea()) + ", hypotenuse: " + String.format("%.2f", getHypotenuse()) + ", color: " + getColor().name().toLowerCase());
}
#Override
public double getArea() {
double p = (side1 + side2 + side3) / 2;
double s = Math.sqrt((p * (p - side1) * (p - side2) * (p - side3)));
return s;
}
#Override
public ColorEnum getColor() {
return color;
}
public double getHypotenuse() {
double hypotenuse = 0;
double[] arr = {side1, side2, side3};
for (double i : arr) {
if (hypotenuse < i) hypotenuse = i;
}
return hypotenuse;
}
}
Circle class:
public class Circle implements Shape {
private double radius;
private ColorEnum color;
public Circle(ColorEnum color, double radius) {
this.color = color;
this.radius = radius;
}
#Override
public void draw() {
System.out.println("Drawing circle, area: " + String.format("%.2f", getArea()) + ", radius: " + String.format("%.2f", getRadius()) + ", color: " + getColor().name().toLowerCase());
}
#Override
public double getArea() {
return Math.PI * Math.pow(radius, 2);
}
#Override
public ColorEnum getColor() {
return color;
}
public double getRadius() {
return radius;
}
}
Trapeze class:
public class Trapeze implements Shape {
private double base1, base2, height;
private ColorEnum color;
public Trapeze(ColorEnum color, double base1, double base2, double height) {
this.color = color;
this.base1 = base1;
this.base2 = base2;
this.height = height;
}
#Override
public void draw() {
System.out.println("Drawing trapeze, area: " + String.format("%.2f", getArea()) + ", height: " + String.format("%.2f", getHeight()) + ", color: " + getColor().name().toLowerCase());
}
#Override
public double getArea() {
return (base1 + base2) / 2 * height;
}
#Override
public ColorEnum getColor() {
return color;
}
public double getHeight() {
return height;
}
}
Now back to random array part. I need random amount of shape's with random parameters. How to nicely implement stuff like this ? Should I use factory pattern ? I accidentally found one implementation on GitHub, can you tell me is it good ?
https://github.com/Ligren/QaTestLab/blob/master/QaTestLab/src/Test/ShapeDrawing.java and https://github.com/Ligren/QaTestLab/blob/master/QaTestLab/src/Test/Start.java
So, I finished this task, and employer approved it :)
You can check final version on GitHub:
https://github.com/Wonderio619/QATestTask
Related
I'm trying to write a program that states the color and area of a circle using String color and int radius using sets and gets. Using green & 10 as an example. Here's what I have so far:
public class Circle
{
private String color;
private int radius;
public Circle () {
color = "null";
radius = 0;
}
public Circle (String setColor, int setRadius) {
}
public void setRadius (int radius) {
this.radius = radius;
}
public void setColor(String color) {
this.color = color;
}
public int getRadius(){
return radius;
}
public String getColor(){
return color;
}
public void printInfo(String setColor, int setRadius) {
double area = Math.PI * this.radius * this.radius;
System.out.printf("The " + "%s" + " circle has area " + "%.2f",
this.radius, area);
}
}
public class Main
{
public static void main(String [] args)
{
Circle circle = new Circle("green", 10);
circle.printInfo();
}
}
"circle.printInfo();" has an error and I'm not sure why. Still pretty new to this so any help is appreciated. Thanks!
In the constructor which takes arguments, you forgot to include code which defines the Circle. Right now, you create a circle with undefined variable, even though you passed it information. How to fix:
public Circle (String color, int radius) {
this.setRadius(radius);
this.setColor(color);
}
I believe you thought the arguments in the constructor took the place of the methods you created, but you are creating and defining local variables with the same name as the methods instead.
Hope this helps! Comment on anything that confuses you.
I have an interface that has one ordinary method and one generic method. I have implemented ordinary method for two different classes, but do not now how to do that with generic method. Here is my code:
Sphere.java:
public class Sphere implements GeometricShape<Sphere> {
private double radius;
public Sphere (double radius) {
this.radius = radius;
}
public double volume() {
return (4.0 / 3.0) * Math.PI * radius * radius * radius;
}
public void describe() {
System.out.println("Sphere[radius=" + radius + "]");
}
#Override
public Sphere supersize()
{
this.radius*=2;
return new Sphere(radius);
}
}
Rectangle.java
public class Rectangle implements TwoDShape {
private double width, height;
public Rectangle (double width, double height) {
this.width = width;
this.height = height;
}
public double area()
{
return width * height;
}
public double perimeter()
{
return 2.0 * (width + height);
}
public void describe()
{
System.out.println("Rectangle[width=" + width + ", height=" + height + "]");
}
#Override
public Rectangle supersize()
{
this.width*=2;
this.height*=2;
return new Rectangle(width, height);
}
}
TwoDShape.java:
public interface TwoDShape extends GeometricShape
{
public double area();
}
ThreeDShape.java:
public interface ThreeDShape extends GeometricShape<ThreeDShape>
{
public double volume();
}
GeometricShape.java:
public interface GeometricShape<T extends GeometricShape<T>>
{
public void describe();
public T supersize();
}
and finally main class ArrayListExample.java:
import java.util.ArrayList;
public class ArrayListExample {
public static void describe_all( ArrayList<? extends GeometricShape> shapes )
{
for(int i=0;i<shapes.size();i++)
{
shapes.get(i).describe();
}
System.out.println("Total number of shapes:"+ shapes.size());
}
public static void main(String[] args) {
System.out.println("The describe() method:");
System.out.println();
System.out.println("Example rectangles");
ArrayList<Rectangle> rects = new ArrayList<Rectangle>();
rects.add(new Rectangle(2.0, 3.0));
rects.add(new Rectangle(5.0, 5.0));
describe_all(rects);
System.out.println();
ArrayList<Sphere> spheres = new ArrayList<Sphere>();
spheres.add(new Sphere(10.0));
spheres.add(new Sphere(50.0));
spheres.add(new Sphere(0.0));
System.out.println("Example spheres");
describe_all(spheres);
System.out.println();
System.out.println("The supersize() method:");
System.out.println();
ArrayList<Rectangle> double_rects = supersize_list(rects);
describe_all(double_rects);
System.out.println();
ArrayList<Sphere> double_spheres = supersize_list(spheres);
describe_all(double_spheres);
}
}
How can I implement supersize_list method that it takes supersize method from both rectangle and sphere and outputs like
Rectangle[width=4.0, height=6.0]
Rectangle[width=10.0, height=10.0]
Total number of shapes: 2
Sphere[radius=20.0]
Sphere[radius=100.0]
Sphere[radius=0.0]
Total number of shapes: 3
Could you help me with this, please? I greatly appreciate your help!
The class hierarchy looks inconsistent. For example, you have ThreeDShape extends GeometricShape<ThreeDShape> and TwoDShape extends GeometricShape at the same time, for no obvious reason. It's not fun to write a generic method for these types.
Here's a less-confusing version. (I hope) Note: I choose not to change the size of the shape itself in supersize method, instead let it return a bigger shape while keeping the original unchanged.
1. GeometricShape
/**
* A geometric shape interface. You can do two things with it.
* 1. Ask it to describe itself (to stdout);
* 2. Ask it to return a bigger version of itself (double the size).
*/
public interface GeometricShape<T extends GeometricShape<T>> {
/**
* Print a description to STDOUT
*/
void describe();
/**
* Returns a bigger shape.
* #return Something that's a GeometricShape
*/
T supersize();
}
2. Shape2D and Rectangle
/**
* A 2-dimensional shape.
* It has area.
* Its supersize() method should return a Shape2D instance.
*/
public interface Shape2D<T extends Shape2D<T>> extends GeometricShape<T> {
double area();
}
/**
* A rectangle.
*/
public final class Rectangle implements Shape2D<Rectangle> {
private final double width;
private final double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
#Override
public String toString() {
return "Rectangle{" +
"width=" + width +
", height=" + height +
'}';
}
#Override
public void describe() {
System.out.println(this);
}
#Override
public Rectangle supersize() {
return new Rectangle(width*2, height*2);
}
#Override
public double area() {
return width * height;
}
}
3. Shape3D and Sphere
/**
* A 3-dimensional shape.
* It has volume.
* Its supersize() method should return a Shape3D instance.
*/
public interface Shape3D<T extends Shape3D<T>> extends GeometricShape<T> {
double volume();
}
/**
* A sphere
*/
public final class Sphere implements Shape3D<Sphere> {
private final double radius;
public Sphere(double radius) {
this.radius = radius;
}
#Override
public String toString() {
return "Sphere{" +
"radius=" + radius +
'}';
}
#Override
public void describe() {
System.out.println(this);
}
#Override
public Sphere supersize() {
return new Sphere(radius*2);
}
#Override
public double volume() {
return 4*Math.PI*Math.pow(radius, 3)/3;
}
}
Now the generic method that transforms a list
public static <T extends GeometricShape<T>>
List<T> supersize_list(List<T> list) {
List<T> result = new ArrayList<>();
for (T shape : list) {
result.add(shape.supersize());
}
return result;
}
You do not need to return a new Object. For Rectangle for example
#Override
public void supersize()
{
this.width*=2;
this.height*=2;
}
is sufficient
What's up guys,
I keep receiving this error, cannot find symbol Circle aCircle = new Circle(); , when trying to compile the driver code my professor gave us. I'm wondering if it is because I haven't added it to my circle.java method. This is the circle driver.
package lab7;
public class CircleDriver {
public static void main(String[] args) {
Circle aCircle = new Circle();
aCircle.setColor("green");
aCircle.setRadius(10);
aCircle.display();
Double circleArea = aCircle.computeArea();
Double circumference = aCircle.computeCircumference();
System.out.println("circle area: " + circleArea);
System.out.println("circle circumference: " + circumference);
System.out.println();
}
}
This is my circle method.`
public class Circle {
private String color;
private int radius;
public Circle(String color, int radius) {
this.color = color;
this.radius = radius;
}
public Circle() {
Circle aCircle = new Circle();
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getRadius() {
return radius;
}
public void setRadius(int radius) {
this.radius = radius;
}
public void display() {
System.out.println("I am a circle");
System.out.println("My color is " + color);
System.out.println("My radius is " + radius);
}
public double computeArea() {
return (Math.PI * Math.pow(radius, 2));
}
public double computeCircumference() {
return (2 * Math.PI * radius);
}
}
You need to call a super() constructor when calling a circle. When you call
Circle aCircle = new Circle();
You are trying to initialize a circle in the local aspect. I think you are trying to inherit the Circle class that is already in java.
Leaving the circle constructor as
public Circle() {}
Should theoretically work to instantiate your class.
Use this code. You have mistake in constructor. I hope it will solve your issue.
In Circle.java, instead of
public Circle() {
Circle aCircle = new Circle();
}
Use this code
public Circle() {
super();
// TODO Auto-generated constructor stub
}
CircleDriver.java
public class CircleDriver {
public static void main(String[] args) {
Circle aCircle = new Circle();
aCircle.setColor("green");
aCircle.setRadius(10);
aCircle.display();
Double circleArea = aCircle.computeArea();
Double circumference = aCircle.computeCircumference();
System.out.println("circle area: " + circleArea);
System.out.println("circle circumference: " + circumference);
System.out.println();
}
}
Circle.java
public class Circle {
private String color;
private int radius;
public Circle() {
super();
// TODO Auto-generated constructor stub
}
public Circle(String color, int radius) {
super();
this.color = color;
this.radius = radius;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getRadius() {
return radius;
}
public void setRadius(int radius) {
this.radius = radius;
}
public void display() {
System.out.println("I am a circle");
System.out.println("My color is " + color);
System.out.println("My radius is " + radius);
}
public double computeArea() {
return (Math.PI * Math.pow(radius, 2));
}
public double computeCircumference() {
return (2 * Math.PI * radius);
}
}
Output:
I am a circle
My color is green
My radius is 10
circle area: 314.1592653589793
circle circumference: 62.83185307179586
Doing a what I thought would be a very very easy output lab for AP, I thought I was doing everything correctly, but the output keeps coming out as "The area is :: " + 0.0" when the "0.0" is supposed to be the calculated area of the circle. Here are the two classes:
Circle Class:
public class Circle
{
private double radius;
private double area;
public void setRadius(double rad)
{
rad = radius;
}
public void calculateArea( )
{
area = (3.14159*(radius*radius));
}
public void print( )
{
System.out.println("The area is :: " + area);
}
}
Circle Runner Class:
public class CircleRunner
{
public static void main( String[] args )
{
Circle test = new Circle ( );
test.setRadius(7.5);
test.calculateArea( );
test.print( );
test.setRadius(10);
test.calculateArea( );
test.print( );
test.setRadius(72.534);
test.calculateArea( );
test.print( );
test.setRadius(55);
test.calculateArea( );
test.print( );
}
}
Thanks!
Your setter is wrong, so your radius stays 0, it should be
public void setRadius(double rad) {
radius = rad;
}
You are assigning the variables in reverse order. It should be:
radius = rad;
And not:
rad = radius;
You need to use this to reference your radius in your setRadius Method. or swap the two values. You should assign " rad " to " radius" and not vis versa, since you will be recieving rad from the method.
public class Circle {
private double radius;
private double area;
public Circle() {
}
public void setRadius(double rad) {
this.radius = rad;
}
public void calculateArea() {
area = (3.14159*(radius*radius));
}
public void print() {
System.out.println("The area is :: " + area);
}
}
I need to take information from a file and create them into objects and put them into an array so I can compare the areas of the objects and list in the array which object has the largest area and its location in the array.
I'm confused on how I take the information from the file and create each one into a object (circle or rectangle) and then assign that object into an array after it has been created. I think my other classes are fine, I'm just stuck on finishing the driver.
Normally, I would do something like Circle c1 = new Circle(); to create a new object, but how do I do that from a file with predefined information and assign it to an array?
Data:
“CIRCLE”, 1, “blue”, true
“RECTANGLE”, 1, 2, “blue”, true
“RECTANGLE”, 10, 2, “red”, true
“CIRCLE”, 2, “green”
“RECTANGLE”
“CIRCLE”
Driver:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class Driver {
public static void main(String[] args) throws FileNotFoundException {
Scanner input = new Scanner(new File("C:/Users/Charles/Desktop/GeometricObjectsData.txt"));
ArrayList<GeometricObject> list = new ArrayList<GeometricObject>();
while (input.hasNext()) {
String line = input.nextLine();
System.out.println(line);
}
}
}
GeometricObject:
public abstract class GeometricObject {
//class variables
private String color;
private boolean filled;
//constructors
public GeometricObject() {
super();
color = "white";
filled = false;
}
public GeometricObject(String color, boolean filled) {
super();
this.color = color;
this.filled = filled;
}
//mutators
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public boolean isFilled() {
return filled;
}
public void setFilled(boolean filled) {
this.filled = filled;
}
//user-defined methods
public abstract double getArea();
public abstract double getPerimeter();
#Override
public String toString() {
return super.toString() + " \tColor=" + this.getColor() + " \tFilled=" + this.isFilled();
}
}
Circle:
public class Circle extends GeometricObject {
//class variables
private double radius;
//constructors
public Circle() {
super();
radius = 1;
}
public Circle(double radius, String color, boolean filled) {
super(color, filled);
this.radius = radius;
}
//mutators
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
//user-defined methods
#Override
public double getArea() {
//area of a circle
return (radius * radius * Math.PI);
}
#Override
public double getPerimeter() {
//perimeter of a circle
return (2 * radius * Math.PI);
}
#Override
public String toString() {
return super.toString() + "\nCircle: Radius=" + this.getRadius();
}
}
Rectangle:
public class Rectangle extends GeometricObject {
//class variables
private double height;
private double width;
//constructors
public Rectangle() {
super();
height = 1;
width = 1;
}
public Rectangle(double height, double width, String color, boolean filled) {
super(color,filled);
this.height = height;
this.width = width;
}
//mutators
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
//user-defined methods
#Override
public String toString() {
return super.toString() + "\nRectangle: Height=" + this.height + "\tWidth=" + this.width;
}
#Override
public double getArea() {
return (height * width);
}
#Override
public double getPerimeter() {
return (2 * height + 2 * width);
}
}
In your text file, you have special quotes around your shape items. This will make your life more difficult, so you should change that, if possible
Example of how to make objects (from your main method):
while (input.hasNext()) {
String line = input.nextLine();
System.out.println(line);
String[] parts = line.split(",");
if (parts[0].indexOf("Circle") != -1) {
Circle c = new Circle();
// ... parse the rest of the attributes to set up your circle
} else if ... // fill in the other shape cases
}