【问题标题】:Why doesn't my toString() method properly override the toString() method in its superclass?为什么我的 toString() 方法不能正确覆盖其超类中的 toString() 方法?
【发布时间】:2019-05-07 16:37:59
【问题描述】:

我正在编写一个带有toString() 方法的子类,我希望在数组列表中读取该子类的项目时打印该方法,但是当该类型的项目被读取时,它只会打印超类的toString()被添加到数组列表中。这是子类的代码:

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

    }
}

这是超类Products中的toString

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

}

我这里是包含主要方法的类的一部分,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);


    }

哪个打印:

  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

但它应该打印:

  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

我是否需要 MultiBuyProduct 本身的主要方法,或者我可以使用 ShoppingCart 中的主要方法吗?如果需要,我可以为上下文提供更多代码。

编辑:我找到了问题的根源。在ShoppingCart.add() 中,我检查了该项目,如果它不在arraylist 中,它会创建该项目的副本并将其添加到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)Product 中定义为

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

}

这意味着MultiBuyProduct 类型的任何项目都会丢失它们的minDiscountedQuantitydiscountPercent 值。我不确定如何解决这个问题,因为我无法将 public Product(Product p) 扩展到 MultiBuyProduct

【问题讨论】:

  • System.out.println(newCart); 调用newCarttoString,这是一个ShoppingCart - 你还没有发布。所以我只能假设它永远不会调用你的toString()MultiBuyProduct
  • 我已经更新了我的其他 toString() 方法。我相信ShoppingCart 它将Product 类型的每个项目添加到toString() 并且由于MultiBuyProductProduct 的子类,这也应该将multibuyproducts 添加到toString(),对吗?我还展示了 ShoppingCart 是如何构建的。

标签: java overriding subclass tostring


【解决方案1】:

这是一些示例代码。请看看这是否是您的应用程序试图做的事情(这是行为)吗?

该示例有一个Animal 类。 Dog扩展 Animal。两者都覆盖了java.lang.ObjecttoString 方法。

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


输出:

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

【讨论】:

  • 谢谢,除了toString()中的一些格式错误,我的MultiBuyProduct类很好,问题在于如何将项目添加到ShoppingCart的arraylist中,我在我的详细说明最近的编辑。
  • 问题在于如何将商品添加到 ShoppingCart 中的数组列表中您知道问题是什么并且您找到了解决方案吗?
  • 正如我所说,我详细说明了主要问题。 ShoppingCart.add() 方法创建项目的副本以添加到数组列表中,这样原始项目就不会被编辑。问题是该副本仅包含Product 的变量,不包含来自MultiBuyProduct 的任何变量,因此当MultiBuyProduct 通过ShoppingCart.add() 传递时,它会丢失其变量。我不知道如何解决这个问题
  • Product 有多个构造函数?
  • 是的,它有一个用于创建初始项目,一个用于创建该项目的副本以添加到数组列表中
猜你喜欢
  • 1970-01-01
  • 2012-01-11
  • 2018-01-10
  • 2018-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-28
  • 1970-01-01
相关资源
最近更新 更多