3

我是菜鸟,Java 是我的第一门编程语言。我有这个我正在尝试解决的问题:

定义一个类来表示糖碗糖,其特征在于三个方面:总容量(以克为单位)、可用数量和勺子的数量(多少克糖占用与其相关联的勺子)。在此类中设置:

  1. 创建糖罐的构造方法。
  2. 一种可以知道糖碗中糖含量的方法。
  3. 一种可以知道一勺糖需要多少的方法。
  4. 一种方法,给定一些勺子,移除相应数量的糖,返回这个值。
  5. 一种加糖的方法。如果提供的值超过可用空间,糖碗应该是满的,剩余的量会被退回。在其他情况下,应该返回零。

将课程设置RunSugarBowl为主要课程并玩耍。

public class SugarBowl {

    private int totalCapacity;
    private int availableSpace;
    private int spoonSize;
    private int occupiedSpace = totalCapacity-availableSpace;//is the same as amount of sugar in the bowl.

    SugarBowl (int totalCapacity){
        availableSpace=totalCapacity;
        spoonSize = totalCapacity/20;//arbitrary size
    }

    public int spoon(){
        return spoonSize;
    }

    public int occupied(){
        return occupiedSpace;
    }

    public void scoops (int numberOfScoops){
        int amountTaken = numberOfScoops * spoonSize;
        if (amountTaken<=occupiedSpace){
            occupiedSpace=occupiedSpace-amountTaken;
            System.out.println(amountTaken);}
        else{
            System.out.println("There's not that amount of sugar in the sugar bowl. Try less.");}       
    }
    public int addSugar (int addedAmount){
        if (addedAmount>availableSpace){
            int remainingAmount=addedAmount-availableSpace;
            availableSpace=0;
            occupiedSpace = totalCapacity-availableSpace;
            return remainingAmount;}
        else{
             availableSpace = availableSpace - addedAmount;
             occupiedSpace = totalCapacity-availableSpace;
                return 0;}
    }
}

现在的问题是我的one.occupied方法返回0而不是200在:

public class RunSugarBowl {
    public static void main(String[] args) {
        SugarBowl one = new SugarBowl(200);
        one.addSugar(300);
        System.out.println("Occupied size is : "+ one.occupied());
    }
}
4

6 回答 6

3

不幸的是,您的代码是错误的。你应该改变这个功能

    public void addSugar (int addedAmount){
    if (addedAmount>availableSpace){
        int remainingAmount=addedAmount-availableSpace;
        System.out.println("Sugar bowl completely full. You got left: "+ remainingAmount);}
    else{
        System.out.println("0");}
}

public void addSugar (int addedAmount){
    if (addedAmount>availableSpace){           
        System.out.println("Sugar bowl completely full. You got left: "+ remainingAmount);}
    else{
        availableSpace = availableSpace - addedAmount; //this ensures available space changes after you add sugar
        occupiedSpace = totalCapacity-availableSpace; // you must also write this to change the ocuuppied space too
        System.out.println(availableSpace);
    }
}

因为您构建了容量为 200 的糖罐,然后再添加 100。所以

if (addedAmount>availableSpace) 

100 > 200 返回 false,它直接进入 else 块,它只打印出 '0'。这是你犯的逻辑错误。但别担心我们都去过那里;)

实际上,这条线 occupiedSpace = totalCapacity-availableSpace; 是必不可少的, availableSpace = availableSpace - addedAmount; 因为您使用了占用空间作为属性。您在类开头编写的公式仅执行一次,当您调用构造函数时(最初您提取的两个值都是 0,因为它们是原始 int)并且占用空间保持为0,除非您使用其他函数调用更改它.

但是,如果您希望每次需要时都计算占用空间或可用空间,则应删除其中一个,因此您只需要另一个和totalCapacity。每次可以通过从totalCapacity中减去一个来计算另一个。如果我是你,我会用

public int getOccupiedSpace(){
return totalCapacity-availableSpace;
}

而不是使用(顺便说一句,这对您的情况有用)

private int occupiedSpace = totalCapacity-availableSpace;

这是一样的

private int occupiedSpace = 0;

或者

private int occupiedSpace ;
于 2012-12-27T18:51:29.590 回答
2

首先,作为提示,添加方法标头很有用,这样您就知道您的方法要做什么。Aka,如果您查看您的规范,您的许多方法都要求您“知道多少......”所以这些方法应该返回一个数字,而不是立即打印出一些东西(我在开始编码时犯了同样的错误)。

您正在您的方法中打印出这些数字(这对调试很有用,但不是您的成品应该做什么)。您可以返回一个 int,然后在 RunSugarBowl 中打印出该整数(见下文)。

我已经为您提供了一个总体框架,并添加了一些可能对您有所帮助的评论。你一开始就做得很好。如果您有更多问题,请在评论中提问。

public class SugarBowl {
    private int totalCapacity;
    private int availableSpace;
    private int spoonSize;
    private int occupiedSpace;//starts at 0, because there's nothing in the bowl.

    /**
     * Constructor for the sugar bowl.
     * @param totalCapacity     The total capacity of the bowl.
     */
    public SugarBowl (int totalCapacity){
        this.totalCapacity = totalCapacity; //set the totalCapacity for the bowl
        availableSpace=totalCapacity;
        spoonSize = totalCapacity/20;//arbitrary size
        occupiedSpace = 0;
    }
    /**
     * Shows how much sugar can fit in a spoon.
     * @return  The size of the spoon
     */
    public int spoon(){
        return spoonSize;
    }
    /**
     * Returns amount of sugar in the bowl.
     * @return  The amount of occupied space
     */
    public int occupied(){
        return occupiedSpace;
    }
    /**
     * Removes the amount of sugar based on the
     * number of scoops passed into it.
     * @param numberOfScoops    The number of scoops
     * @return          The amount of sugar removed
     */
    public int scoops (int numberOfScoops){

        int possibleAmountTaken = numberOfScoops * spoonSize;
        int actualAmountTaken = 0;
        //Think about sugar, even if there is less sugar than the spoon size, 
        //can a spoon still remove that amount?
        //aka the only time 0 sugar should be taken is when there is 0 sugar in the bowl
        if (possibleAmountTaken<=occupiedSpace){
            actualAmountTaken = possibleAmountTaken;
        }
        else{
            //there may still be sugar, just not enough for every scoop, you still have to remove it
            //actualAmountTaken = ???
        }
        occupiedSpace = occupiedSpace - actualAmountTaken;
        //what about availableSpace?
        //availableSpace = ???
        return actualAmountTaken;       
    }
    /**
     * Adds the specified amount of sugar to the bowl.
     * 
     * @param addedAmount   The amount of sugar added to the bowl
     * @return  The overflow amount of sugar or 0 if there was no overflow
     */
    public int addSugar (int addedAmount){
        int overflow = 0;
        if (addedAmount>availableSpace){
            overflow = addedAmount-availableSpace;
            //your bowl is going to be full, what happens to occupiedSpace and availableSpace?
            //availableSpace = ???
            //occupiedSpace = ???
        }
        else{
            //overflow is already 0 so you don't have to do anything with it
            //update availableSpace and occupiedSpace
            //availableSpace = ???
            //occupiedSpace = ???
        }
        return overflow;
    }
}

用你上面的主要例子:

public class RunSugarBowl {
    public static void main(String[] args) {
        SugarBowl one = new SugarBowl(200);
        System.out.println("Sugar overflow: " + Integer.toString(one.addSugar(300))); //once working correctly should print out 100 for the overflow
        System.out.println("Occupied size is : "+ one.occupied());
    }
}

更新

您使用 this.totalCapacity 的原因是因为以下代码行:

public class SugarBowl {
    private int totalCapacity; //totalCapacity for this object; aka this.totalCapacity refers to this variable
    //..

    public SugarBowl (int totalCapacity){ // <-- totalCapacity passed in
        this.totalCapacity = totalCapacity; //this.totalCapacity is setting the totalCapacity for this instance of the object to the value passed in
        //..

请注意您的构造函数是如何在名为“totalCapacity”的变量中传递的,但该类也有自己的内部变量,称为totalCapacity。没有“this”关键字的可比代码如下:

public class SugarBowl {
    private int bowlTotalCapacity; //totalCapacity for this object
   //..

    public SugarBowl (int totalCapacity){ 
        bowlTotalCapacity = totalCapacity;
        //..

您只需确保在初始化之前使用过 totalCapacity 的任何位置后,将其更改为 bowlTotalCapacity。使用 this.totalCapacity 来引用此类中的 totalCapacity 要容易得多。在这里查看更多信息:http ://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html 。

从技术上讲,您在最初构造对象后实际上并没有再次使用 totalCapacity,但是如果您想查看如果不包含此部分会发生的奇怪情况,请尝试了解以下代码中发生的情况:

public class ThisExample {
    private int wrongExample = 0;
    private int thisExample = 0;

    public ThisExample (int wrongExample, int thisExample){
        wrongExample = wrongExample;
        this.thisExample = thisExample; 
    }

    public int getThisExample(){
        return thisExample;
    }
    public int getWrongExample(){
        return wrongExample;
    }
}

运行以下命令可以帮助您更好地理解:

public class ThisExampleMain {
    public static void main(String[] args) {
        ThisExample ts = new ThisExample(50, 50);
        //you want this to be 50 but it ends up being 0:
        System.out.println("Wrong: " + ts.getWrongExample());
        //this returns the correct answer:
        System.out.println("Right: " + ts.getThisExample());
    }
}
于 2012-12-27T19:49:30.057 回答
2

规范要求的 addSugar 方法应该返回一个 int:addSugar 方法还应该同时更新 availableSpace 和占用空间。

在 main 中,您正在调用 one.occupied() 方法,但您没有对该值做任何事情,也许您想打印它以查看它。

以下是您的 addSugar 方法和主要方法。

public int addSugar (int addedAmount){
    if (addedAmount>availableSpace){
        int remainingAmount=addedAmount-availableSpace;
        return remainingAmount;
        }
    else
        {
            availableSpace = availableSpace - addedAmount;
            occupiedSpace = occupiedSpace + addedAmount;
        return 0;
        }
}

public class RunSugarBowl {
public static void main(String[] args) {
    SugarBowl one = new SugarBowl(200);
    System.out.println("The occupied Space is: " + one.occupied());
    System.out.println("The addSugar() method is returning " + one.addSugar(300));
    System.out.println("The occupied Space now is: " + one.occupied());
}

}

于 2012-12-27T20:17:17.407 回答
1

您的 main 方法调用这些方法,但不使用从这些方法返回的值。你应该改变你的main方法如下。

public class RunSugarBowl {
    public static void main(String[] args) {
        SugarBowl one = new SugarBowl(200);
        System.out.println("Occupied size is : "+ one.occupied());
    }
}

如下更改您的 addSugar() 方法。

    public void addSugar (int addedAmount){
        if (addedAmount>availableSpace){
            int remainingAmount=addedAmount-availableSpace;
            availableSpace=0;
//Update occupiedSpace here.

            System.out.println("Sugar bowl completely full. You got left: "+ remainingAmount);}
        else{
             availableSpace = availableSpace - addedAmount; //this ensures available space changes after you add sugar
                System.out.println("I added "+addedAmount + "to the bowl");
// Update occupiedSpace here.


    }
    }

添加糖时,您不会更新您的占用空间字段。这就是它始终保持不变的原因。

于 2012-12-27T18:38:52.220 回答
0

你应该更换

sugarBowl (int totalCapacity){
    availableSpace=totalCapacity;
    spoonSize = totalCapacity/20;//arbitrary size
}

经过

public SugarBowl (int totalCapacity){
    availableSpace=totalCapacity;
    spoonSize = totalCapacity/20;//arbitrary size
}
于 2012-12-27T18:20:57.837 回答
0

您可以将该main()方法添加到您的sugarBowl类中。您不需要单独的类来运行它。

我会像这样修改你的主要内容:

public class RunSugarBowl {
    public static void main(String[] args) {
        sugarBowl one = new sugarBowl(200);
        one.occupied();
        one.addSugar(100);
        }
}

或者您可以将您的类及其构造函数重命名为SugarBowl. 我推荐第二个,因为它符合 Sun Java 编码标准。

于 2012-12-27T18:23:51.213 回答