'how to call length, width, height, area, volume of a box from box class using boxTest
I am writing a code to measure the surface area of a box and volume of the box. Finally, I got it to works. Now the challenges are I have to make 4 object and and store it into array and then use enhanced for loop to go through each box in the array. I mean when you loop through the array, it will get to first box, and ask you to enter the length, width, and height. Then it will show you the first box's length, width, height, surface area, and volume. I try to find an example for it but I cant find anything. I am still trying to make it work. Thank you for your help. here is my Box code.
public class Box
{
private double length = 1.0;
private double width = 1.0;
private double height = 1.0;
//constructor
public Box (double l, double w, double h)
{
setLength(l);
setWidth(w);
setHeight(h);
}
//set length method
public void setLength(double l)
{
if(l > 0)
{
length = l;
}
else
{
length = 1.0;
}
}
//set width method
public void setWidth(double w)
{
if(w > 0)
{
width = w;
}
else
{
width = 1.0;
}
}
//set height method
public void setHeight(double h)
{
if(h > 0)
{
height = h;
}
else
{
height = 1.0;
}
}
//calculate area method
public double calculateArea(double length, double width)
{
return (length*width);
}
//calculate volume method
public double calculateVolume(double length, double width, double height)
{
return (length*width*height);
}
//get length method
public String getLength()
{
return String.format("%f", length);
}
//get width method
public String getWidth()
{
return String.format("%f",width);
}
//get height
public String getHeight()
{
return String.format("%f",height);
}
public String toString()
{
return String.format("Length is %s.\nWidth is %s.\nHeight is %s.\n", getLength(), getWidth(), getHeight());
}
}
and here is my main code
import java.util.Scanner;
public class BoxTest
{
public static void main(String[] args)
{
//Box boxOne, boxTwo, boxThree, boxFour;
double l;
double w;
double h;
Scanner input = new Scanner(System.in);
int[] boxes = new int[4];
System.out.print ("Enter the length of your box:");
l= input.nextDouble();
System.out.print ("Enter the width of your box:");
w= input.nextDouble();
System.out.print ("Enter the height of your box:");
h= input.nextDouble();
Box boxOne = new Box(l, w, h);
System.out.println(boxOne.toString());
System.out.printf("The surface area of the box is %f.\nThe volume of the box is %f.\n",
boxOne.calculateArea(l, w), boxOne.calculateVolume(l, w, h));
}
}
Solution 1:[1]
Because you do not use semicolons to separate parameters, use commands instead.
Also if you're passing a parameter you don't need to specific the type.
Try using Box boxOne = new Box(length, width, height);
Solution 2:[2]
You haven't declared those doubles
in your constructor.
it should be like this:
double l = 50.55;
double w = 40.99;
double h = 12.33;
Box boxOne = new Box(l, w, h);
...
EDIT:
I just saw that you are trying to get the values from the Scanner
.
You should first read them, store them in the variables, and then create a new
instance of Box
. Not the other way around.
So,
Scanner input = new Scanner(System.in);
System.out.print ("Enter the dimension of your box:");
l= input.nextDouble();
w= input.nextDouble();
h= input.nextDouble();
Box boxOne = new Box(l, w, h);
...
Solution 3:[3]
See changes and comments in the code:
public class Box
{
private double length; // No need to set default values here
private double width; // No need to set default values here
private double height; // No need to set default values here
//alternative constructor
public Box()
{
//Just instantiate the box, but do not set anything.
}
//constructor
public Box (double l, double w, double h)
{
this.length = l; // Don't use method calls that can be overridden in
this.width = w; // your constructor.
this.height = h;
}
//set length method
public void setLength(double l)
{
if(l > 0)
{
this.length = l; // You have to use this.length to set
// the value stored in the object
}
else
{
this.length = 1.0;
}
}
//set width method
public void setWidth(double w)
{
if(w > 0)
{
width = w; // same as above
}
else
{
width = 1.0; // same as above
}
}
//set height method
public void setHeight(double h)
{
if(h > 0)
{
height = h; // same as above
}
else
{
height = 1.0; // same as above
}
}
//calculate area method
public double calculateArea() // don't use new parameters. Instead use the values
// stored in the object (this.length and this.width)
{
return (this.length * this.width);
// the formula is not correct, because this only calculates the area
// of one side of the box, but I will let you figure that out yourself ;-)
}
//calculate volume method
public double calculateVolume() // same as above
{
return (this.length * this.width * this.height);
}
//get length method
public String getLength()
{
// It's not advisable to convert the type of the variable
// in a standard getter, you should rather use something like
// getLengthAsString and use getLength to return the length as
// it is.
return String.format("%f", this.length); // You have to use this.length to return
// the value stored in the object
}
//get width method
public String getWidth()
{
return String.format("%f",width); //same as above
}
//get height
public String getHeight()
{
return String.format("%f",height); //same as above
}
public String toString()
{
return String.format("Length is %s.\nWidth is %s.\nHeight is %s.\n", getLength(), getWidth(), getHeight());
}
For the main function:
To declare an array of 4 boxes you would do:
Box[] boxes = new Box[4];
And to put a box at the first position in the array:
boxes[0] = new Box();
then read the user input and set the box-properties accordingly:
newBox.setHeight(scanner.nextDouble());
newBox.setLength(scanner.nextDouble());
newBox.setWidth(scanner.nextDouble());
This should give you all you need to fix the problem.
Solution 4:[4]
My recommendation is to break the problem into sub-problems and create a solution for each. This is called Problem Decomposition. Once all of the solutions are created, integrate them. In theory, integrating all of the solutions together should solve the entire problem. In your case, I think this a good, logical way to decompose your problem:
- Box creation (Setting dimension on each Box)
- Storing the boxes
- Calculating Volume
- Calculating Surface Area
- Capturing user input
- Iterating through Box collection
Box Creation
My recommendation is that, since all these subproblems are all related to your Box
object, create helper classes and/or methods to handle each one. In this case, you can create a method that given height, width, and length, returns a new instance of Box
.
public static Box createBox (int height, int width, int length) {
return new Box(height, width, length);
}
In turn, your Box
class should be storing these parameters as global members:
public class Box {
private final int height, width, length;
public Box (int height, int width, int length) {
this.height = height;
...
}
... (other methods omitted)
}
I know this looks like overkill, and I agree. BUT, what this does is teach you a very valuable lesson in Single Responsibility Principle as well as code modularization which helps testing these smaller jobs independently. I am a strong believer that, helper classes should contain nothing but static methods. Why? Because it doesn't make much sense to create instances of objects that never hold data. In Java, Math
class is an example of what I am talking about.
Alternatively, you could create boxes without dimension and set the height, width, and length separately, but I don't believe this is a good way to go about it. For example, if one or more parameters are not set, you could end up with erroneous behavior. Lastly, your Box
class should create immutable objects so that dimensions cannot be changed once an instance of the class is created. I will address this point last.
Storing the boxes
If this is a single-class project, maybe you want to make this collection (most likely a java.util.List
type) a global attribute of your class. If this project contains more than one class, the class that calls your createBox
method will have some code to add the return value of this method into some list. Something like this should do:
Box box1 = BoxUtils.createBox(1, 2, 3);
myList.add(box1);
Box box2 = BoxUtils.createBox(4, 5, 6);
myList.add(box2);
...
You get the idea. That said, this should be better done in a loop. We will get back to this later. For now, just remember this is NOT done by the box utilities or helper class. This is done by the class that calls it; in your case, BoxTest
public class BoxTest {
public static void main(String[] args) {
// TODO get user input
// create box
// add box to list
...
}
Calculate Volume
This method should be in Box
class...
box.getVolume();
Since the parameters are passed via the constructor, you don't need to pass them to this method again. However, you could argue that since you have a utilities class for all box related helper methods, you could move this responsibility there and have the Box
class to be a simple POJO (that does not how to calculate its own volume or area). I prefer this approach. If you decide to do this, you need to pass a Box
instance to the helper method and return the result.
Box box = new Box(1, 2, 3);
int volume = BoxUtils.calculateVolume(box); // preferred
Calculate Surface Area
This method should also be in Box
class or box utilities...
int area = box.getSurfaceArea(); // In Box, or
int area = BoxUtils.getSurfaceArea(box); // in BoxUtils (preferred)
Capturing User Input
Iterating through the collection of boxes was left for last for a reason. I think you should firs try to get your problem working with a single box first. Make sure you open and close your Scanner
object properly, get the user input correctly, etc. Then, once you test your solution to your satisfaction, expand your solution to capture inputs and create boxes in a loop operation. That way if it fails, you know your problem is isolated to this one part of the problem and not something else. For situations like this is why Problem Decomposition is crucial.
Your original problem uses double
for your height, width, and length. I am using int
for simplicity.
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter height, width, and length for the box (space-separated i.e. 10 20 30)");
int height = input.nextInt();
int width = input.nextInt();
int length = input.nextInt();
input.close();
Box box = new Box(height, width, length);
System.out.println(box); // I overrode Object#toString() in Box class to do this.
}
My output
Enter height, width, and length for the box (space-separated i.e. 10 20 30)
10 20 30
height: 10; width: 20; length: 30
Iterating Through Box Collection
You mentioned that you wanted to use enhanced for loop for this. You probably won't be able to do this for what I am recommending. See this article for details. Instead, a traditional for loop will do just fine. Since I know everything has worked so far, I can now modify my existing solution to introduce looping to capture the user inputs
public static void main(String[] args) {
Box[] boxArray = new Box[4];
Scanner input = new Scanner(System.in);
for (int i = 0; i < boxArray.length; i++) {
System.out.println("\nEnter height, width, and length for the box (space-separated i.e. 10 20 30)");
int height = input.nextInt();
int width = input.nextInt();
int length = input.nextInt();
Box box = new Box(height, width, length);
System.out.println(box);
// TODO print volume and area
}
input.close();
}
Notice that the code is basically the same. I just created an array to store the boxes and a loop to repeat capturing the user's input until the array is full (4 boxes). You could modify this loop to go on forever and only break after a special character is pressed (which is out of scope for what you need to do).
Once I get this part done, it is time to add printing out (calculate) the volume and area for each box. You can do this inside the same loop (recommended) or create another loop and iterate through the array to display these results.
Now, to finish, I just replaced the TODO with the following code:
System.out.println("Box " + (i+1) + " surface area: " + BoxUtils.calculateSurfaceArea(box));
System.out.println("Box " + (i+1) + " volume: " + BoxUtils.calculateVolume(box));
Now when I execute the code, I will get an output that resembles the following:
Enter height, width, and length for the box (space-separated i.e. 10 20 30)
1 2 3
Box 1 surface area: 22.0
Box 1 volume: 6.0
Coding for Immutability
Coding for immutability is out of scope for your requirement, but I think it is important to mention. Immutability has many benefits, one of which is thread safety. It is obviously not without drawbacks, but in my opinion the benefits outweighs them. For this example, I just made the fields of the Box
class private
and final
, and I did not provide setter methods. So, your Box
class should look like this:
public class Box {
private final int height, width, length;
public Box(int height, int width, int length) {
this.height = height;
this.width = width;
this.length = length;
}
public int getHeight() {
return height;
}
public int getWidth() {
return width;
}
public int getLength() {
return length;
}
@Override
public String toString() {
return "height: " + height + "; " + "width: " + width + "; " + "length: " + length;
}
}
Your BoxUtils
like this:
public class BoxUtils {
private BoxUtils() {
throw new AssertionError("BoxUtils cannot be instantiated");
}
public static Box createBox (int height, int width, int length) {
return new Box(height, width, length);
}
public static double calculateVolume(Box box) {
return box.getWidth() * box.getHeight() * box.getLength();
}
public static double calculateSurfaceArea(Box box) {
int width = box.getWidth();
int height = box.getHeight();
int length = box.getLength();
return 2 * ((width * length) + (height * length) + (height * width));
}
}
and finally your BoxTest
like this:
public class BoxTest {
public static void main(String[] args) {
Box[] boxArray = new Box[4];
Scanner input = new Scanner(System.in);
for (int i = 0; i < boxArray.length; i++) {
System.out.println("\nEnter height, width, and depth for the box (space-separated i.e. 10 20 30)");
int height = input.nextInt();
int width = input.nextInt();
int depth = input.nextInt();
Box box = new Box(height, width, depth);
System.out.println("Box " + (i+1) + " surface area: " + BoxUtils.calculateSurfaceArea(box));
System.out.println("Box " + (i+1) + " volume: " + BoxUtils.calculateVolume(box));
}
input.close();
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Konato_K |
Solution 2 | |
Solution 3 | |
Solution 4 |