简体   繁体   中英

Why doesn't my toString() method properly override the toString() method in its superclass?

I'm writing a subclass with a toString() method which I would like to be printed when items of that subclass are read in an arraylist, however it just prints the toString() of the superclass when an item of that type is added to an arraylist. Here is the code for the subclass:

package shop;

import java.text.DecimalFormat;

public class MultiBuyProduct extends Product{
private int minDiscountedQuantity;
private int discountPercent;

public MultiBuyProduct(String name, double price, int quantity, int minDiscountedQuantity, int discountPercent) {
    super(name, price, quantity);
    this.minDiscountedQuantity = minDiscountedQuantity;
    this.discountPercent = discountPercent;
}

    //getters and setters

    public double getTotalPrice() {
        if (getQuantity() >= getMinDiscountedQuantity()) {
            double total = getPrice() * getQuantity();
            double discountedTotal = total - ((discountPercent/100) * total); 
            return discountedTotal;
        }
        return getPrice() * getQuantity();
    }

    public double discount() {
        double total = getPrice() * getQuantity();
        double discount = (discountPercent/100) * total;
        return discount;
    }


    @Override
    public String toString() {
        DecimalFormat format = new DecimalFormat("#.00");
        return String.format("%s,\n%20s%5.2f)", super.toString(), format.format(getTotalPrice()), "(Multibuy Discount: GBP ", discount());

    }
}

This is the toString in the superclass Products

public String toString() {
    DecimalFormat format = new DecimalFormat("#.00");
    return String.format("%3d * GBP %5s  %-20s= GBP %7s", quantity, format.format(price), 
                        name, format.format(getTotalPrice()));

}

I have this here are parts of the class which contains the main method, ShoppingCart :

public class ShoppingCart {
private ArrayList<Product> cart;

    public ShoppingCart() {
        cart = new ArrayList<>();
    }
    @Override
    public String toString() {
        double total = 0;
        StringBuilder sb = new StringBuilder();
        for (Product p : cart) {
            sb.append(p.toString()).append("\n");
            total += p.getTotalPrice();
        }
        sb.append(String.format("%48s \n%40s%8.2f", "------------", "TOTAL GBP", total));
        return sb.toString();
    }

    public static void main(String[] args) {
        ShoppingCart newCart = new ShoppingCart();

        Product apple, milk, caulk, ice, snakes;
        MultiBuyProduct snakesMulti;
        apple = new Product("Apples (4 pack)", 1.20, 1);
        milk = new Product("Milk (1l)", 0.75, 1);
        caulk = new Product("Caulk (1l)", 6.84, 1);
        ice = new Product("Ice (1kg)", 4.30, 1);
        snakes = new Product("Snake (5m)", 32.0, 1);
        snakesMulti = new MultiBuyProduct("Snakes", 30.0, 12, 3, 20);

        newCart.add(apple);
        newCart.add(apple);
        newCart.add(apple);
        newCart.add(caulk);
        newCart.add(milk);
        newCart.add(milk);
        newCart.add(snakes);
        newCart.add(ice);
        newCart.add(ice);
        newCart.add(snakesMulti);


        System.out.println(newCart);


    }

which prints:

  3 * GBP  1.20  Apples (4 pack)     = GBP    3.60
  1 * GBP  6.84  Caulk (1l)          = GBP    6.84
  2 * GBP   .75  Milk (1l)           = GBP    1.50
  1 * GBP 32.00  Snake (5m)          = GBP   32.00
  2 * GBP  4.30  Ice (1kg)           = GBP    8.60
 12 * GBP 30.00  Snakes              = GBP  360.00
                                    ------------ 
                               TOTAL GBP  412.54

but it should print:

  3 * GBP  1.20  Apples (4 pack)     = GBP    3.60
  1 * GBP  6.84  Caulk (1l)          = GBP    6.84
  2 * GBP   .75  Milk (1l)           = GBP    1.50
  1 * GBP 32.00  Snake (5m)          = GBP   32.00
  2 * GBP  4.30  Ice (1kg)           = GBP    8.60
 12 * GBP 30.00  Snakes              = GBP  288.00
       (Multibuy Discount: GBP 72.00
                                    ------------ 
                               TOTAL GBP  340.54

Would I need a main method in MultiBuyProduct itself, or can I use the one in ShoppingCart ? I can provide more code for context if it is needed.

Edit: I have found the source of the problem. In ShoppingCart.add() I check through the item, and if it is not already in the arraylist, it creates a copy of the item and adds it to the arraylist:

public void add(Product p) {
    if (cart.size() > 0) {
        for (Product i : cart) {
            if (i.getName().equals(p.getName()) 
                && i.getPrice() == p.getPrice()) {

                i.setQuantity(i.getQuantity() + p.getQuantity());
                return;
            }
        } 
        cart.add(new Product(p)); //this is done because if it were just cart.add(p), it would change the product being assigned as well as the product in the arraylist
    } else {
        cart.add(new Product(p));
    }
}

Product (p) is defined in Product as

public Product(Product p) {
    this.name = p.name;
    this.price = p.price;
    this.quantity = p.quantity;

}

Which means that any items of type MultiBuyProduct lose their minDiscountedQuantity and discountPercent values. I am unsure how to fix this, as I cannot extend public Product(Product p) to MultiBuyProduct

Here is some example code. Please see if this is what is your application trying to do (is this the behavior)?

The example has an Animal class. The Dog class extends Animal . Both have the java.lang.Object 's toString method overridden.

class Animal {

    private String name;

    public Animal(String s) {
        name = s;
    }

    public String toString() {
        return "Animal name: " + name;
    }
}

class Dog extends Animal {

    private String name;

    public Dog(String s) {
        super(s);
        name = s;
    }

    public String toString() {
        return "Dog Name: " + name + ", " + super.toString();
    }
}


Public class TestingInheritance {
    public static void main(String [] args) {

        Animal d0 = new Animal("just animal");  
        Animal d1 = new Dog("mutt");
        Dog d2 = new Dog("pup");

        System.out.println(d0);
        System.out.println(d1);
        System.out.println(d2);
        System.out.println("");

        List<Animal>  anims = Arrays.asList(d0, d1, d2);
        for (Animal a : anims) {
            System.out.println(a.toString());
        }
    }
}


The Output:

Animal name: just animal
Dog Name: mutt, Animal name: mutt
Dog Name: pup, Animal name: pup

Animal name: just animal
Dog Name: mutt, Animal name: mutt
Dog Name: pup, Animal name: pup

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM