如何使用boxTest从box类中调用框的长度,宽度,高度,面积,体积

时间:2014-12-05 22:36:46

标签: java

我正在编写一个代码来测量盒子的表面积和盒子的体积。最后,我得到了它的工作。现在的挑战是我必须制作4个对象并将其存储到数组中,然后使用增强的for循环来遍历数组中的每个框。我的意思是当你循环遍历数组时,它会到达第一个框,并要求你输入长度,宽度和高度。然后它会显示第一个框的长度,宽度,高度,表面积和体积。我试图找到一个例子,但我找不到任何东西。我仍然想让它发挥作用。谢谢您的帮助。这是我的Box代码。

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());
    }

}

这是我的主要代码

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));


    }
}

4 个答案:

答案 0 :(得分:0)

您尚未在构造函数中声明doubles

它应该是这样的:

double l = 50.55;
double w = 40.99;
double h = 12.33;
Box boxOne = new Box(l, w, h);
...

修改

我刚刚看到您正在尝试从Scanner获取值。

您应首先阅读它们,将它们存储在变量中,然后创建new Box实例。不是相反。

所以,

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);
...

答案 1 :(得分:0)

因为您不使用分号来分隔参数,所以请改用命令。

此外,如果您传递参数,则无需特定类型。

尝试使用Box boxOne = new Box(length, width, height);

答案 2 :(得分:0)

请参阅代码中的更改和注释:

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());
    }

主要功能:

要声明一个包含4个框的数组:

Box[] boxes = new Box[4];

将一个方框放在数组的第一个位置:

boxes[0] = new Box();

然后读取用户输入并相应地设置box-properties:

    newBox.setHeight(scanner.nextDouble());
    newBox.setLength(scanner.nextDouble());
    newBox.setWidth(scanner.nextDouble());

这应该为您提供解决问题所需的一切。

答案 3 :(得分:0)

我的建议是将问题分解为子问题并为每个子问题创建一个解决方案。这称为问题分解。创建所有解决方案后,将它们集成。从理论上讲,将所有解决方案整合在一起应该可以解决整个问题。就您而言,我认为这是分解问题的好方法:

  1. 盒子创建(在每个盒子上设置尺寸)
  2. 存放箱子
  3. 计算体积
  4. 计算表面积
  5. 捕获用户输入
  6. 遍历 Box 集合

盒子创建

我的建议是,由于所有这些子问题都与您的 Box 对象相关,因此请创建帮助程序类和/或方法来处理每个问题。在这种情况下,您可以创建一个给定高度、宽度和长度的方法,返回一个新的 Box 实例。

public static Box createBox (int height, int width, int length) {
    return new Box(height, width, length);
}

反过来,您的 Box 类应该将这些参数存储为全局成员:

public class Box {
    private final int height, width, length;
    public Box (int height, int width, int length) {
        this.height = height;
        ...
    }
    ... (other methods omitted)
}

我知道这看起来有点矫枉过正,我同意。但是,这样做是在单一职责原则和代码模块化方面教给您非常宝贵的一课,这有助于独立测试这些较小的工作。我坚信,辅助类应该只包含静态方法。为什么?因为创建从不保存数据的对象实例没有多大意义。在 Java 中,Math 类是我所谈论的一个示例。

或者,您可以创建没有尺寸的框并分别设置高度、宽度和长度,但我认为这不是一个好方法。例如,如果未设置一个或多个参数,您最终可能会出现错误行为。最后,您的 Box 类应该创建不可变对象,以便一旦创建了类的实例就不能更改维度。我将在最后解决这一点。

存放箱子

如果这是一个单类项目,也许您想让这个集合(很可能是 java.util.List 类型)成为您的类的全局属性。如果此项目包含多个类,则调用您的 createBox 方法的类将具有一些代码来将此方法的返回值添加到某个列表中。应该这样做:

Box box1 = BoxUtils.createBox(1, 2, 3);
myList.add(box1);
Box box2 = BoxUtils.createBox(4, 5, 6);
myList.add(box2);
...

你懂的。也就是说,这应该更好地在循环中完成。我们稍后会回到这个话题。现在,请记住这不是由 box 实用程序或 helper 类完成的。这是由调用它的类完成的;就您而言,BoxTest

public class BoxTest {
    public static void main(String[] args) {
        // TODO get user input
        // create box
        // add box to list
        ...
}

计算体积

这个方法应该在 Box 类中...

box.getVolume();

由于参数是通过构造函数传递的,所以不需要再次传递给这个方法。但是,您可能会争辩说,因为您有一个用于所有与框相关的辅助方法的实用程序类,您可以将这个责任移到那里,并将 Box 类设为一个简单的 POJO(它不如何计算自己的体积或区域)。我更喜欢这种方法。如果您决定这样做,则需要将 Box 实例传递给辅助方法并返回结果。

Box box = new Box(1, 2, 3);
int volume = BoxUtils.calculateVolume(box); // preferred

计算表面积

此方法也应该在 Box 类或框实用程序中...

int area = box.getSurfaceArea(); // In Box, or
int area = BoxUtils.getSurfaceArea(box); // in BoxUtils (preferred)

捕获用户输入

由于某种原因,将遍历框的集合留到最后。我认为您应该首先尝试使用单个盒子解决您的问题。确保正确打开和关闭 Scanner 对象,正确获取用户输入等。然后,一旦您对解决方案进行了满意的测试,请扩展您的解决方案以捕获输入并在循环操作中创建框。这样,如果它失败了,您就知道您的问题与问题的这一部分无关,而与其他问题无关。对于这种情况,问题分解至关重要。

您的原始问题使用 double 作为您的高度、宽度和长度。为简单起见,我使用 int

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.
}

我的输出

Enter height, width, and length for the box (space-separated i.e. 10 20 30)
10 20 30
height: 10; width: 20; length: 30

遍历 Box 集合

您提到要为此使用增强的 for 循环。您可能无法按照我的建议执行此操作。有关详细信息,请参阅 this article。相反,传统的 for 循环就可以了。由于我知道到目前为止一切正常,我现在可以修改我现有的解决方案以引入循环来捕获用户输入

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();
}

注意代码基本相同。我刚刚创建了一个数组来存储框和一个循环来重复捕获用户的输入,直到数组已满(4 个框)。您可以修改此循环以使其永远持续下去,并且仅在按下特殊字符后才中断(这超出了您需要执行的范围)。

完成这部分后,是时候添加打印(计算)每个盒子的体积和面积了。您可以在同一个循环中执行此操作(推荐)或创建另一个循环并遍历数组以显示这些结果。

现在,为了完成,我只是用以下代码替换了 TODO:

System.out.println("Box " + (i+1) + " surface area: " + BoxUtils.calculateSurfaceArea(box));
System.out.println("Box " + (i+1) + " volume: " + BoxUtils.calculateVolume(box));

现在,当我执行代码时,我将得到类似于以下内容的输出:

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

不变性编码

不变性编码超出了您的要求,但我认为值得一提。不变性有很多好处,其中之一就是线程安全。这显然不是没有缺点,但在我看来,好处大于它们。在这个例子中,我只是创建了 Box 类的字段 privatefinal,我没有提供 setter 方法。因此,您的 Box 类应如下所示:

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;
    }
}

你的 BoxUtils 像这样:

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));
    }
}

最后你的BoxTest是这样的:

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();
    }
}