1

Please I am trying to get the items of an order, the items are coffee muffin and timBits, by using the method

public String toString()

Every thing is working properly except that I do not get the items of the order I get null for them instead of the following:

    Muffin   "Bran"              ,3
    Coffee   "Latte"             , 1
    TimBits  "Assorted"         , 24
    Muffin   "Chocolate"        , 1
    Coffee   "Decaf"            , 2
   TimBits   "Chocolate"        , 12
   Muffin    "PeanutButter"     , 2
   Muffin    "Blueberry"        , 5

the numbers above represents the quantity of each item in the order.

class Item
{
  protected String description;
  protected int quantity;
  protected String kind;
  private double cost;

   public double getCost()
   {
      return this.cost;
   }

 public Item (String description, int quantity)
 {
   this.description = description;
   this.quantity = quantity;
 }

 public String toString()
 {
   return "Item: " + "      " +kind + "      " + ": description: "  + "      " +description  +"quantity:" +"        " + quantity ;

 }

 class Coffee extends Item
{
  protected double cost1Coffee;
  String kind = "Coffee";
  public Coffee (String description, int quantity)


 {
   super(description, quantity);
   cost1Coffee = 4 ;
 }

 }
}


 class Muffin extends Item
{
  protected double cost1Muffin;
  protected double cost2Muffin;
  protected double cost3Muffin;
  String kind = "Muffin";
  public Muffin (String description, int quantity)

 {
   super(description,quantity);
   cost1Muffin = 1;
   cost2Muffin = 0.75;
   cost3Muffin = 0.50;
 }



}


 class TimBits extends Item
{
 protected double  cost1TimBits ;
 String kind = "TimBits";
 public TimBits (String description, int quantity)

 {
   super(description, quantity);
   cost1TimBits = 0.25;
 }

}



/***************************************************************/
/***************************************************************/

class A4Q1Util
{
 private static ArrayList<Item> order;

 private static int count = 0;

 public static Item getItem()
 {
  Item item;

  if (order==null)
  {
   order = new ArrayList<Item>();

   order.add(new Muffin("Bran", 3));
   order.add(new Coffee("Latte", 1));
   order.add(new TimBits("Assorted", 24));
   order.add(new Muffin("Chocolate", 1));
   order.add(new Coffee("Decaf", 2));
   order.add(new TimBits("Chocolate", 12));
   order.add(new Muffin("PeanutButter", 2));
   order.add(new Muffin("Blueberry", 5));
  }

  item = null;
  if (count<order.size())
  {
   item = order.get(count);
   count++;
  }
  {
  return item;
  }


 }
}



output:

Item:       null      : description:       Branquantity:        3 
Item:       null      : description:       Lattequantity:        1 
Item:       null      : description:       Assortedquantity:        24 
Item:       null      : description:       Chocolatequantity:        1 
Item:       null      : description:       Decafquantity:        2 
Item:       null      : description:       Chocolatequantity:        12 
Item:       null      : description:       PeanutButterquantity:        2 
Item:       null      : description:       Blueberryquantity:        5 

Program completed normally.

1
  • 2
    If your question is answered, accept the appropriate answer, do not remove your quesiton from the site! Commented Nov 15, 2013 at 18:52

4 Answers 4

4

Don't declare the field kind in every sub-class. Add the assignment to the constructors, e.g.:

public TimBits (String description, int quantity) {
    super(description, quantity);
    kind = "TimBits";
    cost1TimBits = 0.25;
}
Sign up to request clarification or add additional context in comments.

5 Comments

Actually, why isn't the current solution working? That is, what's wrong with assigning kind outside of the constructor.
@Keikoku that's called hiding of fields. I've updated my answer to explain this.
@Keikoku Because the compiler will use the "first match". Declaring the variable in the child class will "hide" the original field in the child class and assignments to kind will therefore be made to the sub-class field, not the super-class field.
The toString() is inherited by the children and therefore wouldn't it be the case that when a child calls toString() it'll grab its own kind?
@Keikoku No, because toString() is still a method of Item and therefore accesses the field of the class Item. If you wrote the same method again in each of the child classes, you'd get the output you expect.
2

In your Item#toString method:

public String toString() {
    return "Item: " + "      " +kind + "      " + ": description: "  + "      " +description  +"quantity:" +"        " + quantity ;
}

You use kind variable, but never initialize it through your application.

This is because you're hiding the kind field on every child class. Instead, declare it as protected in parent class and just initialize it accordingly on each child.

class Coffee extends Item {
    protected double cost1Coffee;
    //drop this
    //String kind = "Coffee";
    public Coffee(...) {
        super(...);
        kind = "Coffee";
    }
}

You can even be more restrictive about the kind field by marking it as final and disallowing any other class modifying it except its children when executing the constructor. A sample of this:

class Item {
    //other fields...
    protected final String kind;
    protected Item (String description, int quantity, String kind) {
        this.description = description;
        this.quantity = quantity;
        this.kind = kind;
    }
    public Item (String description, int quantity) {
        this(description, quantity, "uncategorized");
    }
}

class Coffee extends Item {
    public Coffee(String description, int quantity) {
        //similar in other subclasses of Item
        super(description, quantity, "Coffee");
    }
}

Comments

0

You're assigning to String kind inside each subclass of Item. However, this kind is not the same as the kind field of the superclass Item since the subclass field masks that of the superclass. You have two options to fix this.

  1. Expand the Item constructor to accept a String kind and add to the call to super.

     super(description,quantity,"Muffin");
    
  2. Assign to kind inside the subclass constructors so that the correct kind is assigned to (the one declared in Item which is used by toString()).

     public Muffin (String description, int quantity)
     {
        kind = "Muffin";
     }
    

Comments

0

It looks like you never initialize your variable kind and even though you are extending from the superclass "Item" throughout all of your child classes, you're simply overloading the variable name kind and redefining it. Therefore when you make the call to the toString() method, your parent class (Item) never gets it's kind variable initialized. What you need to do is also set the kind in the constructor so that you can pass it in through super().

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.