我在比较从另一个类导入的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");
}
}
答案 0 :(得分:2)
您只需更改add
课程中的Products
- 方法即可。假设您将Purchase
- 对象存储在Product
类的列表中,它可能看起来像这样:
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
。 :)
答案 1 :(得分: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;
}
}
}
此时您已经明确注意到我们需要添加选项并处理它们。
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子类的流程方法如下所示。
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(); 私人地图篮=新的HashMap();
在这种情况下,您对增量或添加的调用将如下所示:
if (basket.containsKey(item)){
int quantity = basket.get(item) + 1;
basket.set(item, quantity);
} else {
basket.set(item, 1);
}
虽然这很长,但它触及了许多清理此代码的方法,将责任放在它所属的位置以及最简单的位置,并解决您的问题。如果Map
类对您的需求不满意,您可能会考虑这样一种情况,即您有一个Item
类,其中包含一个库存商品和一个PurchasedItem
类,该类扩展了该类,即你买的东西。这是另一个讨论。