java 如何使用boxTest从Box类中调用Box的长度、宽度、高度、面积、体积

gopyfrb3  于 2023-05-21  发布在  Java
关注(0)|答案(4)|浏览(200)

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

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

    }
}
dzjeubhm

dzjeubhm1#

由于不使用分号分隔参数,因此请改用命令。
同样,如果你传递一个参数,你不需要指定类型。
尝试使用Box boxOne = new Box(length, width, height);

qncylg1j

qncylg1j2#

你还没有在构造函数中声明那些doubles
应该是这样:

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

编辑

我刚刚看到你试图从Scanner中获取值。
您应该首先读取它们,将它们存储在变量中,然后创建Boxnew示例。而不是反过来。
那么

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

e1xvtsh33#

查看代码中的更改和注解:

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

然后读取用户输入并相应地设置框属性:

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

这应该给予你所有你需要解决的问题。

hk8txs48

hk8txs484#

我的建议是将问题分解为子问题,并为每个子问题创建解决方案。这被称为***问题分解。创建所有解决方案后,将其集成。从理论上讲,将所有解决方案集成在一起应该可以解决整个问题。在你的情况下,我认为这是一个很好的,合乎逻辑的方法来分解你的问题:
1.长方体创建(设置每个长方体的尺寸)
1.存放箱子
1.计算体积
1.计算表面积
1.捕获用户输入
1.遍历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)
}

我知道这看起来有点过分,我同意。但是,这所做的是教你一个非常有价值的教训,在单一责任原则以及代码模块化,这有助于测试这些较小的工作独立。我坚信,helper类应该只包含静态方法。为什么?因为创建从不保存数据的对象的示例没有多大意义。在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相关的helper方法,那么您可以将此职责移到那里,并将Box类设置为简单的POJO(不计算其自身的体积或面积)。我更喜欢这种方法。如果您决定这样做,则需要将Box示例传递给helper方法并返回结果。

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

相关问题