2016-11-19 51 views
1

我已经编写了一个程序,该程序从文件读入并将信息存储在我自己创建的集合类中。我的程序工作正常,但是我想知道是否有任何事情可以改善我的程序并通过继承和其他Java功能防止重复的代码。这是我的课程。我添加了评论来解释每个班级的工作。通过继承改进程序

abstract class Order { //superclass 
private int quantity; //instance variables 

public Order(int quantity) { //constructor 
    this.quantity = quantity; 
} 

public int getQuantity() { // instance method 
    return quantity; 
} 

public abstract double totalPrice(); 

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

} //super Class Order 

class Coffee extends Order { //subclass 
private String size; //instance variables 

public Coffee (int quantity, String size) { //constructor 
    super(quantity); 
    this.size = size; 
} 

public double totalPrice() { //instance method to calculate price for the item 
    double priceSmall = 1.39; 
    double priceMed = 1.69; 
    double priceLar = 1.99; 
    double total = 0; 

    if (size.equals("small")) { 
    total = priceSmall * getQuantity(); 
    } else { 
    if (size.equals("medium")) { 
    total = priceMed * getQuantity(); 
    } else { 
    if(size.equals("large")) { 
     total = priceLar * getQuantity(); 
    } 
    } 
} 
    return total; 
} //totalPrice 


public String toString() { 
return "Coffee ("+ size + "): " + super.toString() ; 
} 

} //coffee sub-class 

class Donuts extends Order { //sub-class 
private double price; //instance variables 
private String flavour; 

public Donuts(int quantity, double price, String flavour) { //constructor 
super(quantity); 
this.price = price; 
this.flavour = flavour; 
} 


public double totalPrice() { //instance method to calculate price 
double total = 0; 
int quantity = getQuantity(); 

if(quantity < 6) { 
    total = (price * quantity); 
    double tax = 0.07 * total; 
    total += tax; 
} else { 
    total = price * quantity; 
} 
return total; 
} //totalPrice 

public String toString() { 
return "Donuts("+ flavour + "): " + super.toString() + ", price: " + price; 
} 

} //class Donuts 

class Sandwich extends Order { //Sub-class 
    private double price; // instance variables 
    private String filling; 
    private String bread; 

// constructor 
    public Sandwich (int quantity, double price, String filling, String bread) { 
    super(quantity); 
    this.price = price; 
    this.filling = filling; 
    this.bread = bread; 
} 

    public double totalPrice() { //instance method 
    double total = 0; 
    int quantity = getQuantity(); 

    total = (price * quantity); 
    double tax = 0.07 * total; 
    total += tax; 

    return total; 
    } //totalPrice 


    public String toString() { 
    return "Sandwich ("+ filling + ") (" + bread + "): "+ super.toString() + 
    ", price: " + price ; 
} 

} // Sandwich class 

    class Pop extends Order { //sub-class 
    private String size; 
    private String brand; 

    public Pop(int quantity, String size, String brand) { //constructor 
    super(quantity); 
    this.size = size; 
    this.brand = brand; 
    } 

    public double totalPrice() { //instance method 
    double priceSmall = 1.79; 
    double priceMed = 2.09; 
    double priceLar = 2.49; 
    double total = 0; 

    if (size.equals("small")) { 
    total = priceSmall * getQuantity(); 
} else { 
    if (size.equals("medium")) { 
    total = priceMed * getQuantity(); 
    } else { 
    if(size.equals("large")) { 
     total = priceLar * getQuantity(); 
    } 
    } 
} 
return total; 
} //totalPrice 

public String toString() { 
    return "Pop ("+ brand + ") (" + size + "): " + super.toString() ; 
} 
} // class Pop 

有四种产品,即咖啡,甜甜圈,三明治和砰砰声的订单我存储,然后打印其总价格。

我正在读的文件的示例是这样的:

咖啡,3,介质

甜甜圈,7,0.89,巧克力

流行,5,大,图示!可口可乐

三明治,1,3.89,神秘的肉,37粒全麦

我的计划是一点点长,但我希望如果是这样的社会可以帮助我提高我的程序。我正在寻求改进的是,我有totalPrice()方法,我在每个班级压倒一切。但是,如果仔细观察coffee类和pop类的属性有点相似。 donut班和sandwiches班同样如此。有没有办法可以防止这些类中的代码重复? 我希望一切都是不言自明的,如果有需要的解释我愿意提供。

回答

2

继承有时在OO系统中被过度使用。一般来说,组合是一种更好的技术 - 阅读“继承与组合”。

对于这种情况,具体而言,您尝试将商店中的库存商品视为订单,这很奇怪,可能没有帮助。一个订单有与它相关的项目,但这些项目本身并不是一个订单。

在这方面你可以有一个类,StoreItem,有一个名称和价格。你也可以让这个类有一个可选的size属性来影响价格。因此,对于商店商品,您可以调用item.getName()和item.getPrice()。当您构建商店物品时,您可以使用namd和价格,或者具有尺寸的物品的名称,尺寸和价格来初始化它。

然后,您可以拥有一个Store类,并且该商店有一个物品清单 - 可用物品清单。订单中列出了物品清单,您的成本计算可能会在订单类中发生一次。它只是通过它的物品清单循环,并询问每个物品的价格。

有了这个解决方案,你最终会得到Item,Store,Order和一个主程序,但是为了扩展你的问题以包含更多的项目,你根本不需要添加任何新的类。

+0

根据您的回答判断您是否暗示我没有任何重要的代码重复?尽管如此,我明白了你对StoreItem类的看法。 – Saad

+0

嗯,没有重复不是可扩展性的问题 - 要添加项目与您的解决方案,您需要添加类。尽管这种解决方案对于价格的大小如何影响价格,但确实存在重复,只需要拥有一个StoreItem类即可消除。 –

0

虽然你的程序也很好,并且他们也可以根据规范对你的问题提供多种解决方案。

你指定的第一件事就是要避免重复,尤其是在totalPrice()方法中,如果必须添加一些更改,可能会导致问题,尤其是在方法totalPrice()中,您会影响所有类。例如,您希望在总价格中添加1%的折扣。考虑到这一点我如下修改建议:

//add utility interface which can be used by all Concrete product classes 
interface PriceCalculator { 

    static double totalPrice(Map<String, Double> priceMap,String size, int quantity) throws Exception{ 
     Double rate=priceMap.get(size); 
     if(rate==null){ 
      throw new Exception("something really bad happened.Missing price"); 
     } 

     return (rate * quantity); 
    } 

} 

class Coffee extends Order { //subclass 
    private String size; //instance variables 
    private Map<String, Double> priceMap=new HashMap<>(); 

    public Coffee (int quantity, String size) { //constructor 
     super(quantity); 
     this.size = size; 
     priceMap.put("priceSmall", 1.39); 
     priceMap.put("priceMed", 1.69); 
     priceMap.put("priceLar", 1.39); 
    } 

    @Override 
    public double totalPrice() { //instance method to calculate price for the item 
     try { 
      return PriceCalculator.totalPrice(priceMap, size, getQuantity()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      return 0; 
     } 
    } //totalPrice 


    public String toString() { 
     return "Coffee ("+ size + "): " + super.toString() ; 
    } 

} //coffee sub-class 

如果问另一个指标是使定价不难coded.You可以通过使用属性类来加载外部文件的键值对尺寸的价格做到这一点。