The problem I was given:
Write an abstract superclass encapsulating a shape: a shape has 2 abstract methods: one returning the perimeter of the shape, another returning the area of the shoe. It also has a constant field named PI. This class has two non-abstract subclasses: one encapsulating a circle, and the other encapsulating a rectangle. A circle has one additional attribute, its radius. A rectangle has 2 additional attributes, its width and height. You also need to include a client class to test these two classes.
Here's the work I've done:
Shape.java
public abstract class Shape
{
public abstract double getPerimeter();
public abstract double getArea();
}
Circle.java
public class Circle extends Shape
{
private double radius;
final double pi = Math.PI;
//Defualt Constructor, calls Shape default constructor
public Circle()
{
//Set default value to radius
this.radius = 1;
}
public Circle(double radius)
{
this.radius = radius;
}
public double getArea()
{
//Return πr^2 (area formula)
//Use Math.pow method (page 141) in order to calculate exponent
return (pi * Math.pow(radius, 2));
}
public double getPerimeter()
{
//Return 2πr (perimeter formula)
return (2 * pi * radius);
}}
Rectangle.java
public class Rectangle extends Shape
{
private double width, height;
public Rectangle()
{
//set default value to width and height
this.width = 1;
this.height = 1;
}
public Rectangle(double width, double height)
{
this.width = width;
this.height = height;
}
public double getArea()
{
return width * height;
}
public double getPerimeter()
{
return 2 * (width + height);
}}
ShapeClient.java
public class ShapeClient {
public static void main(String [] args)
{
// To test Rectangle...
double width = 13, length = 9;
Shape rectangle = new Rectangle(width, length);
System.out.println("The rectangle width is: " + width
+ " and the length is: " + length
+ "The area is: " + rectangle.getArea()
+ "and the perimeter is: " + rectangle.getPerimeter() + ".");
//To test Circle...
double radius = 3;
Shape circle = new Circle(radius);
System.out.println("The radius of the circle is: " + radius
+ "The area is: " + circle.getArea()
+ "and the perimeter is: " + circle.getPerimeter() + ".");
}}
My question is: Does the constant field for PI need to be in the Shape class rather than the Circle class? If so, how should I about taking it out of the circle class and how should I place it in the Shape class?
The abstract class should only contain fields & methods that are general to all shapes such as getArea and getPerimeter.
In this case PI is only specific to the Circle shape or to rephrase, the square has no use for the constant PI. PI should therefore only reside in the 'Circle' class and not the Shape class.
The PI attribute definitely needs to be on the Circle class. The abstract Shape class should contain attributes and methods that all of its sub-classes are going to use or implement. In this case, the Rectangle class has no need for the PI attribute.
just move the constant to the abstract class.
Related
I'm currently undertaking a Java class (one of my final ones for my bachelor, yay) and I'm having a really difficult time trying to understand classes and do this problem below. The textbook I'm currently using is quite confusing and I've tried to use other online resources to figure out what I'm doing wrong but I still seem stuck on the question below. Whenever I try and run the program all I get is 0.00.0 for my answer, is this due to myself incorrectly assigning values to cylinder1? Also, for the toString() class how do I even go about doing this? I'm always getting errors on converting doubles to Strings no matter what I can do.
Any help would be appreciated it.
Thanks.
Prompt
Implement the class called Cylinder shown in UML below. The constructor accepts and initializes the radius and height for the Cylinder, while accessors and mutators allow them to be changed after object construction. The class also include methods that calculate and return the volume and surface area of the Cylinder. Lastly, it contains a toString method that returns the name of the shape, its radius, and its height. Create a main method which instantiates 4 Cylinder objects (any parameters), display them with toString(), change one parameter (your choice) in each, and display them again. [15 points]
UML
Code
import java.util.*;
import java.text.*;
import java.io.*;
import java.lang.*;
class Cylinder
{
private double radius, height, area, volume;
public Cylinder(double height, double radius) {
radius = 0.0;
height = 0.0;
}
public double getRadius() {
return radius;
}
public double getHeight() {
return height;
}
public double getArea() {
double area = (2 * Math.PI * radius * height) + (2 * Math.PI * Math.pow(radius, 2));
return area;
}
public void setRadius(double r) {
radius = r;
}
public void setHeight(double h) {
height = h;
}
public double calcVolume() {
double volume = Math.PI * Math.pow(radius, 2) * height;
return volume;
}
public String toString (){
StringBuilder StBuild = new StringBuilder();
StBuild.append(radius).append(height);
return StBuild.toString();
}
public static void main(String[] args) {
Cylinder cylinder1 = new Cylinder(5, 5);
System.out.println(cylinder1);
}
}
Since this is obviously homework I won't give you the answers, but I'll try to explain a few things.
This:
public Cylinder(double height, double radius) {
radius = 0.0;
height = 0.0;
}
is a constructor. When you create an object (and instance of a class) you call this. You call it by doing:
Cylinder cylinder1 = new Cylinder(5, 5);
But what happens in your class? When you call the constructor are you really saving the values you want?
As for the toString method, you could either call the toString for the double (height.toString) or you could just do what I always end up doing which is just cheat by adding a string to it.
public String toString (){
return "Cylinder [ h: " + height + " - r: " + radius + " - v: " + calcValume() + "]";
}
in class Cylinder change the constructor to:
public Cylinder(double height, double radius) {
this.radius = radius;
this.height = height;
}
In void main() :
Cylinder cylinder1 = new Cylinder(5, 5);
System.out.println(cylinder1.calcVolume());
This will work.
But you should shift the main method to some other class.
In the constructor you are setting the radius and height to 0.0. Try:
public Cylinder(double height, double radius) {
this.radius = radius.
this.height = height;
}
I have written the following code and keep getting the error:
error: cannot find symbol
Circle first = new Circle();
^
symbol: class Circle
location: class TestCircle
error: cannot find symbol
Circle first = new Circle();
^
symbol: class Circle
location: class TestCircle
This is repeated for the second and third as well. Here are the codes:
public class TestCircle {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// Create three Circle objects
Circle first = new Circle();
Circle second = new Circle();
Circle third = new Circle();
// Initialize radius for first and second circles
first.setRadius(6.0);
second.setRadius(15.0);
// Display circle Info
first.displayCircle();
second.displayCircle();
third.displayCircle();
}
}
public class Circle {
//
private double radius; // circle radius
private double diameter; // circle diameter
private double area; // circle area
private final double pi = 3.14159265358979; // value of pi
Circle() // Constructor
{
radius = 1;
diameter = 2 * radius;
area = pi * radius * radius;
}
void setRadius(double rad) // method to set radius and calculate the other two values
{
radius = rad;
diameter = 2 * radius;
area = pi * radius * radius;
}
double getRadius() // method to get radius
{
return radius;
}
void displayCircle() // method to display circle parameters
{
System.out.println("Circle Info");
System.out.println("Radius: " + radius);
System.out.println("Diameter: " + diameter);
System.out.println("Area: " + area);
}
}
Any help in solving this is appreciated.
You need to make your constructor public.
If you don't make it public, then it can only be accessed within the package which is the reason for your error.
It appears that Circle is probably in a different package than TestCircle. If that's the case (if Circle.java has package abcde; or something at the top), then TestCircle will need to import it:
import abcde.Circle;
And, the constructor and all the methods in Circle have to be made public, since the default access ("package-private") doesn't work for a class that's in a different package.
If Circle doesn't have a package statement, then things should work if TestCircle.java and Circle.java are in the same directory. If they're in different directories, but they don't have package statements, then I think you will need to set the CLASSPATH so that it can refer to all the directories where classes exist, or if you're using an IDE, configure it to find things in a different directory. But I'd recommend either using packages or putting things in the same directory.
It's not mandatory to add public before the package. But for a best practice you should make each class in a separate file. And it will work. Try this:
Circle class :
public class Circle {
private double radius; // circle radius
private double diameter; // circle diameter
private double area; // circle area
private final double pi = 3.14159265358979; // value of pi
public Circle() { // Constructor
radius = 1;
diameter = 2 * radius;
area = pi * radius * radius;
}
void setRadius(double rad) // method to set radius and calculate the other two values
{
radius = rad;
diameter = 2 * radius;
area = pi * radius * radius;
}
double getRadius() // method to get radius
{
return radius;
}
void displayCircle() // method to display circle parameters
{
System.out.println("Circle Info");
System.out.println("Radius: " + radius);
System.out.println("Diameter: " + diameter);
System.out.println("Area: " + area);
}
}
TestCircle class:
public class TestCircle {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// Create three Circle objects
Circle first = new Circle();
Circle second = new Circle();
Circle third = new Circle();
// Initialize radius for first and second circles
first.setRadius(6.0);
second.setRadius(15.0);
// Display circle Info
first.displayCircle();
second.displayCircle();
third.displayCircle();
}
}
Notice
If you want to use a single file don't forget to remove the word public before class Circle. Because each class which declared as public should be in a new separate file.
Hey guys so we just started covering objects and classes in my class. I understand creating a new instance of the class pretty well. Howerver, its the data fields and methods im having trouble comprehending. Here is a sample from my book i wrote out. I dont quite get the part where i commmented: "//construct a circle with radius 1. Reason being b.c i declared the double radius in the SimpleCircle class already, so why would i need to write SimpleCircle again? I somewhat understand the accessors and mutators of this program but would like a bit more simple clarification on all this please.
public class TestSimpleCircle {
public static void main(String[] args) {
SimpleCircle circle1 = new SimpleCircle();
System.out.println("The area of the circle of radius " + circle1.radius + " is " + circle1.getArea());
// create a circle with radius 25
SimpleCircle circle2 = new SimpleCircle(25);
System.out.println("The area of the circle of radius " + circle2.radius + " is " + circle2.getArea());
// create a circle with radius 125
SimpleCircle circle3 = new SimpleCircle(125);
System.out.println("The area of the circle of radius " + circle3.radius + " is " + circle3.getArea());
// Modify circle radius of second object
circle2.setRadius(100); //or circle2.setRadius(100);
System.out.println("The area of the circle of radius " + circle2.radius + " is " + circle2.getArea());
} // end main
} // end class
class SimpleCircle {
double radius;
// construct a circle with radius 1
SimpleCircle() {
radius = 1;
}
// construct a circle with a specified radius
SimpleCircle(double newRadius) {
radius = newRadius;
}
// return the are of this circle
double getArea() {
return radius * radius * Math.PI;
}
// return the perimeter of this circle
double getPerimeter() {
return 2 * radius * Math.PI;
}
// set a new radius for this circle
void setRadius(double newRadius) {
radius = newRadius;
}
} // end class
The reason you have two SimpleCircle() statements is because the one is the default constructor, which you technically could omit if you changed double radius; to double radius = 1;. The second allows for the developer to pass a parameter to SimpleCircle(double) of type double and assign it to the field called radius. Both SimpleCircle(...) statements are known as constructors.
Sample output of your program:
The are of the circle of radius 1.0 is 3.141592653589793
The are of the circle of radius 25.0 is 1963.4954084936207
The area of the circle of radius 125.0 is 49087.385212340516
The area of the circle of radius 100.0 is 31415.926535897932
You can see in the first sentence, it used the default constructor which sets the radius equal to 1 or 1.0 because it is a double. The rest use the passed in value for radius or the second constructor.
Because you never assigned your field variable a value in the declaration statement. If you did, then you would not need to set it equal to 1 in the constructor. I hope that answers your question.
This
class SimpleCircle {
double radius;
// construct a circle with radius 1
SimpleCircle() {
radius = 1;
}
Will lead to the same output as this
class SimpleCircle {
double radius = 1;
// construct a circle with radius 1
SimpleCircle() {
}
I'm supposed to find the volume of a cylinder using a Circle object I made in another class. When I create my getVolume method, it tells me I can't multiply a Circle and double, and wanted to know how to fix it. I can't make a getArea method in the Cylinder class, just make a new Circle using a user-inputted radius. Here's the code (first for the Circle class, and second the Cylinder class):
public class Circle {
private double radius;
public Circle(double r) {
radius = r;
}
public double getArea() {
return Math.PI * radius * radius;
}
}
public class Cylinder {
private Circle base;
private double height;
public Cylinder(double r, double h) {
base = new Circle(r);
height = h;
}
public double getVolume() {
return base * height;
}
}
So the getVolume method is my problem. How can I get the program to recognize "base" as a double while it is still a Circle object?
You wanted to write
public double getVolume() {
return base.getArea() * height;
}
Right?
Otherwise, just by thinking of it: do you multiply a circle with a length? No, you multiply an area with a length to get the volume...
Also, if the circle would have a name attribute too, what should be multiplied? There is no magic, the JVM does what you tell it to do.
You need to multiply the area of the circle by the height. But you can't multiply a Circle and a double. Call getArea() on your Circle.
return base.getArea() * height;
return base.getArea() * height
this is my first question here and I'm very new to programming so please bear with me.
I'm taking a java class, and in my current assignment I have to create three instances of a circle, compute their diameters and areas, and print the values. The first two instances are supposed to have the radius set by a setRadius method, while the third is supposed to retain the default calculations based on a radius of 1.
edit: The problem is this: the first two objects, on which I used the setRadius method, returned correct values, but the third was intended to return default values of the constructor, and instead it returned all zeros.
Here is the code, thanks in advance!
//this class implements the Circle class
public class TestCircle
{
public static void main(String[] args)
{
Circle Circle1 = new Circle();
Circle Circle2 = new Circle();
Circle Circle3 = new Circle();
Circle1.setRadius(2);
Circle2.setRadius(10);
Circle1.display();
Circle2.display();
Circle3.display();
}
}
import java.lang.Math.*;
public class Circle
{
double radius;
double diameter;
double area;
public void Circle()
{
radius = 1;
diameter = radius * 2;
area = (radius * radius) * Math.PI;
}
public void setRadius(double rad)
{
this.radius = rad;
diameter = radius * 2;
area = (radius * radius) * Math.PI;
}
public void display()
{
System.out.println("Radius: " + radius);
System.out.println("Diameter: " + diameter);
System.out.println("Area: " + area);
}
}
This
public void Circle()
is just a method with a void return type. For a constructor, you need
public Circle() // notice there is no return type
Because you didn't actually provide a constructor, the following
Circle Circle1 = new Circle();
Circle Circle2 = new Circle();
Circle Circle3 = new Circle();
used a default constructor provided by the compiler. It has an empty body and thus the field values are all initialized to 0 by default.
And since you only call setRadius() on two of them, the other one will only show values of 0.
Read up on constructors here.
Java naming conventions state that variable names should start with lowercase letters and follow a camelCase format. You can do some further reading on this subject here.