1

我在比较从另一个类导入的 myProduct.setRefno(product.getRefno()) 的属性以及描述、价格和数量时遇到问题。我需要能够输入 arefno并且如果篮子容器中存在参考编号,那么我只添加数量而不是所有项目详细信息:

目前程序的工作方式如下:

ref1 description1 price1 1(qty)
ref2 description2 price2 1(qty)
ref1 description1 price1 1(qty)

但是我希望它是:

ref1 description1 price1 2(qty)
ref2 description2 price2 1(qty)

如果它是相同的 refno,那么它只添加数量。

public class Zapper {

    public static void main(String[] args) throws ItemException {
        System.out.println("\n\nThis is Purchases\n\n");

        Products stock=new Products();// Define Variable 
        Products basket=new Products();// Define Variable 
        Purchase product;
        String refno;
        int offer;
        int count;
        int grandtotal;         
        char option;//char variable option

        boolean finished=false;//variable "boolean" set 

        while (!finished) { 
            try {
                option=Console.askOption("\n A)dd P)rint R)emove Q)uit");
                stock.open("stock.lin");
                switch (option) {   
                    case 'A': 
                        product= new Purchase();
                        refno= Console.askString("Enter Ref No:..");
                        product=(Purchase)stock.find(refno);//cast operator 
                        if ( product == null) {
                            System.out.println("Cannot find Ref No");
                        } else {
                            product.print("");
                            Purchase myProduct = new Purchase();
                            myProduct.setRefno(product.getRefno());
                            myProduct.setDescription(product.getDescription());
                            myProduct.setPrice(product.getPrice());
                            myProduct.setQty(1);
                            myProduct.setOffer(product.getOffer());
                            basket.add(myProduct);//add the value of item into Container stock  
                        }
                        break;//end of case statement Add

                    case 'R': 
                        refno= Console.askString("Enter Ref No:..");
                        Product myProduct = new Product();
                        myProduct=(Purchase)basket.find(refno);//cast operator
                        myProduct.setQty(1);
                        if ( myProduct == null)
                            System.out.println("Cannot find Ref No");

                        else {
                            basket.remove(myProduct);
                            basket.print("");   
                        }
                        break;//end of case statement Find

                    case 'P': 
                        basket.print("\nYou have purchased...");
                        break;//end of case statement Print             
                    case 'Q': 
                        finished=true;
                        break;//end of case statement "Q" 
                    case '\0':/*Do Nothing*/
                        break;//end of case statement "Do Nothing"
                    default:    
                        System.out.println("Error: Invalid Option ");
                        break;//end of case statement default
                }
            } catch (ItemException e) {
                System.out.println(e.getMessage());
            } catch (IOException e) {
                System.out.println(e.getMessage());
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }   
        }
        System.out.println("\n\nPurchases Finished \n\n");
    }

}
4

2 回答 2

2

您只需要更改班级add中的 - 方法即可。Products假设您将Purchase-objects 存储在Product类的 List 中,它可能看起来像这样:

private List<Purchase> products; 

public void add(Purchase product) {
    String refNo = product.getRefno();
    for (Purchase p : this.products) { //for every product
        if (p.getRefno().equals(refNo)) { //if two refNumbers equals
            p.setQty(p.getQty() + product.getQty()); //add the desired quantity
            return; //force method to abort
        }
    }
    this.products.add(product); //otherwise, add the new product
}

虽然,我不得不说我发现你的一些类名称有点不寻常。请记住,它们应该始终对它们实际代表的内容给出一个很好的提示,例如,您的Purchase类看起来更像Product. :)

于 2012-07-16T22:49:55.950 回答
0

如果您使用一些适当的 OOP 编码技术,您的很多问题都会消失。

让我们从类的结构开始。

public class Zapper {
    public static void main(String[] args) throws ItemException {
        System.out.println("\n\nThis is Purchases\n\n");

        Products stock=new Products();// Define Variable 
        Products basket=new Products();// Define Variable 
        Purchase product;
        String refno;
        int offer;
        int count;
        int grandtotal;         
        char option;//char variable option

        //Do the work...
    }
}

首先,在任何情况下都不应该 main 抛出异常,更不用说像 ItemException 这样的特定异常。所有这些事情都应该由程序优雅地处理。其次,您实例化了一堆真正应该作为类中的成员字段保存的对象,Zapper.

这可能更符合您的要求:

public class Zapper {
    //These things will stay throughout the program
    private Products stock = new Products();
    private Products basket = new Products();
    private Purchase product;
    private boolean quitSignalReceived = false;
    private Set<Option> options;//A list of keyboard inputs

    public static void main(String[] args) {
        System.out.println("\n\nInitiating Purchase of items\n\n"); //use a proper entrance message to your program

        Zapper zapper = new Zapper();//Create an object! Sets up all class variables on construction.
        zapper.run();//Let a method handle running the program.

        System.out.println("\n\nPurchases Finished \n\n");//Say goodbye!
    }

    public void run() {
        //actually does the work!
    }
}

现在你只需要专注于做什么run()。具体来说,它处理您的“主循环”:

public void run() {
    boolean finished = false;
    stock.open("stock.lin"); //Should happen every time we enter the run() loop
    while (!finished) {
      option=Console.askOption("\n A)dd P)rint R)emove Q)uit");
      processOption(option);
      if (quitSignalReceived) {
          //Do anything that MUST happen before the program quits.
          finished = true;
      }
    }
}

您已经敏锐地注意到此时我们需要在其中添加选项并对其进行处理。

public Zapper() {
   this.options.add(new AddOption());
   this.options.add(new QuitOption());
   //etc.
}

public class Option {
  //Constructor, etc.

  process(String option) {
    for (Option o : options) {
      if (o.getKey.equals(option)) {
        o.process(this);
      }
    }
  }
}

这自然需要一个抽象类 Option,您可以将其子类化:

public abstract class Option {
  public String getKey();//returns the keyboard key associated with this option
  public void process(Zapper z); //actually does what you need the option to do. 
}

让我们考虑一下您的“A”案例:

case 'A': 
                    product= new Purchase();
                    refno= Console.askString("Enter Ref No:..");
                    product=(Purchase)stock.find(refno);//cast operator 
                    if ( product == null) {
                        System.out.println("Cannot find Ref No");
                    } else {
                        product.print("");
                        Purchase myProduct = new Purchase();
                        myProduct.setRefno(product.getRefno());
                        myProduct.setDescription(product.getDescription());
                        myProduct.setPrice(product.getPrice());
                        myProduct.setQty(1);
                        myProduct.setOffer(product.getOffer());
                        basket.add(myProduct);//add the value of item into Container stock  
                    }
                    break;//end of case statement Add

首先,你是new()你的产品,它实例化了一个对象。两行之后,您将变量完全设置为另一个对象。其次,您从不返回对象的方法中获取该对象Purchase,您应该不惜一切代价避免这种情况,并至少封装以防止未来的变化。然后你就会if反对null——这是你应该始终避免的另一种做法。

在添加产品的情况下,您希望 Option 子类的 process 方法如下所示。

public void process (Zapper zap) {
    refno= Console.askString("Enter Ref No:..");
    Purchase stockItem;
    bool success = zap.getPurchase(refno, item);
    if ( !success ) {
        System.out.println("Item not in stock.");//Errors should make sense!
    } else {
        zap.addToBasket(stockItem);
    }
}

这需要将以下方法添加到Zapper

public bool findPurchase(String refno, Purchase item) {
    item = this.stock.find(refno);
    if (item == null) { return false; }
}

public void addToBasket(Purchase item) {
    //actually do the work to add it to your purchases.
}

和产品:

//This method copies the object into a new object and returns it.
public Purchase getPurchaseItem() {
    Purchase myProduct = new Purchase();
    myProduct.setRefno(product.getRefno());
    myProduct.setDescription(product.getDescription());
    myProduct.setPrice(product.getPrice());
    myProduct.setQty(1);
    myProduct.setOffer(product.getOffer());
}

现在,请注意,如果您更改此设置,则会为您完成大量工作: private Products stock = new Products(); 私人产品篮=新产品();

为此: private Map stock = new HashMap(); 私有地图篮 = new HashMap();

在这种情况下,您对 increment-or-add 的调用将如下所示:

if (basket.containsKey(item)){
    int quantity = basket.get(item) + 1;
    basket.set(item, quantity);
} else {
    basket.set(item, 1);
}

虽然这很长,但它涉及许多可以清理此代码的方法,将责任放在它所属的地方和最简单的地方,并解决你的问题。如果Map该类不足以满足您的需求,您可能会考虑这样一种情况,即您有一个Item包含库存商品的PurchasedItem类和一个扩展该商品的类,这就是您购买的东西。那完全是另外一回事了。

于 2012-07-16T23:18:22.290 回答