1

説明、価格、数量とともに別のクラスからインポートされた myProduct.setRefno(product.getRefno()) のプロパティを比較する際に問題が発生しています。キーを入力できるようにする必要がありrefno、参照番号がバスケット コンテナーに存在する場合は、すべてのアイテムの詳細ではなく、数量のみを追加します。

現在、プログラムは次のように動作します。

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メソッドを変更するだけです。-objects をクラスの List にProducts格納するとすると、次のようになります。PurchaseProduct

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

まず第一に、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;
      }
    }
}

この時点で、Options を追加して処理する必要があることに鋭く気付きました。

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()、オブジェクトをインスタンス化する製品です。2 行後、変数を別のオブジェクトに完全に設定します。次に、オブジェクトを返さないメソッドからそのオブジェクトを取得します。これは絶対Purchaseに避け、少なくとも将来の変更に対してカプセル化する必要があります。次に、if反対するスイッチがありますnull-これは、常に避けるべきもう1つの慣行です。

製品を追加する場合、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 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 に答える