user1932739
user1932739

Reputation: 101

Java beginner: classes and methods

I'm a noob and Java is my first programming language. I've this problem that I'm trying to solve:

Define a class to represent a Sugar Bowl sugar characterized by three things: total capacity (in grams), available quantity and quantity of the spoon (how many grams of sugar takes the spoon associated with it). Set in this class:

  1. A constructor method to create a sugar bowl.
  2. A method that allows to know the amount of sugar in the sugar bowl.
  3. A method that allows to know how much it takes a spoonful of sugar.
  4. A method which, given a number of scoops, removes the corresponding amount of sugar, returning this value.
  5. A method to add sugar. If the supplied value exceeds the available space, the sugar bowl should be full, and the remaining amount returned. In other cases, should return zero.

Set the class RunSugarBowl as main and play around.

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

My problem now is that my one.occupied method returns 0 instead off the 200 in:

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

Upvotes: 3

Views: 942

Answers (6)

ARC
ARC

Reputation: 353

First off, just as a tip, it's useful to add method headers so you know what your method is trying to do. Aka, if you look at your specifications many of your methods require you to "know how much..." so the methods should return a number rather than immediately printing something out (I made the same mistake when I began coding).

You are printing out those numbers within your methods (which is useful for debugging, but not what your finished product should do). You can return an int and then print out that integer in your RunSugarBowl (see below).

I've given you a general framework of what that entails and added some comments that may help you. You've done well to begin with. If you have more problems, just ask in a comment.

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

With your above main example:

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

UPDATE

The reason you would use this.totalCapacity is because of the following lines of code:

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

Notice how your constructor is being passed in a variable called "totalCapacity" and yet the class also has its own internal variable called totalCapacity. Comparable code without the "this" keyword is as follows:

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

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

You'd just have to make sure that after you initialize that wherever you would have used totalCapacity before, you'd change it to bowlTotalCapacity. It's just a whole lot easier to use this.totalCapacity to refer to the totalCapacity within this class. Take a look here for more information: http://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html.

Technically you don't actually use totalCapacity ever again after you initially construct the object, but if you want to see the weirdness that happens if you don't include the this portion try to understand what happens in the following code:

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

Running the following may help you understand better:

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

Upvotes: 2

Risin
Risin

Reputation: 21

The addSugar method as required by the spec should return an int: addSugar method should also update both availableSpace and occupiedSpace.

in main you are calling one.occupied() method but you are not doing anything with that value,perhaps you want to print it to see it.

the following is your addSugar method and main.

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

}

Upvotes: 2

Salih Erikci
Salih Erikci

Reputation: 5087

Your main method calls the methods but does not use the values returned from those methods. You should change your main method as follows.

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

Change your addSugar() method as follows.

    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.


    }
    }

You are not updating your occupiedSpace field when you add sugar.That's why it always stays same.

Upvotes: 1

Panda
Panda

Reputation: 21

Your code is wrong unfortunately. You Should change this function

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

with

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

Because you construct your sugar bowl with 200 capacity and addin 100 to it later. So

if (addedAmount>availableSpace) 

100 > 200 returns false and it goes directly to the else block which just prints out '0'. This is the logic error you made. But don't worry we all have been there ;)

Actually the line occupiedSpace = totalCapacity-availableSpace; is essential like availableSpace = availableSpace - addedAmount; since you used occupiedSpace as a property. The formula you wrote at the beginning of the class only executes once, when you call the constructor(and initially both of the values you suctract are 0 since they are primitive int) and occupiedSpace stays as 0 unless you change it with some other function call.

But instead if you want occupiedSpace or availableSpace to be calculated each time you need it you should delete one of them, hence you need only the other one and the totalCapacity. Other one can be calculated each time by subtracting the one from totalCapacity. If I were you I would use

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

instead of using (which are by the way useles for your case)

private int occupiedSpace = totalCapacity-availableSpace;

which is just the same

private int occupiedSpace = 0;

or

private int occupiedSpace ;

Upvotes: 3

duffymo
duffymo

Reputation: 308998

You can add the main() method into your sugarBowl class. You don't need a separate class to run it.

I'd modify your main like this:

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

Or you could rename your class and its constructor to SugarBowl. I'd recommend the second one, because it's consistent with the Sun Java coding standards.

Upvotes: 0

tchike
tchike

Reputation: 164

You should replace

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

by

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

Upvotes: 0

Related Questions