【问题标题】:Adding only sub-classes instances to my collection class仅将子类实例添加到我的集合类
【发布时间】:2017-03-26 03:16:58
【问题描述】:

我正在编写一个具有不同类的程序,并且有一个集合类,它只存储超类的子类。 好的,所以我有一个 Order 超级类来存储数量。代码sn-p是这样的:

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

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

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

 public abstract double totalPrice();

然后我有order 类的子类。子类如下。

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

 public Coffee (int quantity, String size) { //constructor
  super(quantity);
  this.size = size;
 } //... some other methods
} // end of Coffee 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;
 } //...some other methods
} //end of donut class

class Pop extends Order {
 private String size;
 private String brand;

 public Pop(int quantity, String size, String brand) {
  super(quantity);
  this.size = size;
  this.brand = brand;
 } //...again there are some other methods
} //end of pop sub-class

现在这是我需要帮助的地方。我编写了一个包含ArrayList<> 的集合类。代码sn-p是这样的:

class OrderList {
 private ArrayList<Order> list;

 public OrderList() {
  list = new ArrayList<Order>();
}

我想要在集合类中做的是拥有确保只有子类只添加到我的集合类中的实例方法。*

到目前为止我尝试过的是这个(这让我完全是个傻瓜,我知道)。

public void add(Coffee cof) {
 list.add(cof);
}
public void add(Donut don) { // i know we cant have methods with the same name
 list.add(don);
}

public void add(Sandwich sand) {
 list.add(sand);
}

public void add(Pop p) {
 list.add(p);
}

SO 社区,您能否就我的问题给我一些提示。

【问题讨论】:

  • 我准备提供更多细节。
  • 嗯,它永远是一个子类,因为你不能实例化一个抽象类
  • 您只想添加特定的子类吗?
  • 可以拥有同名的方法,重要的是签名。
  • 您只需要一个add(Order order) 方法。由于 Order 是抽象的,您不能直接创建“Order”对象;它只能通过子类创建。 (我假设@flakes 的意思是 can't,而不是 can。)

标签: java class inheritance arraylist collections


【解决方案1】:

您的抽象错误。产品 .. 不是订单。

产品只是一个产品。它有一些“身份”,可能还有不同的“口味”。但是当您考虑它时,最初,这不是命令。当客户选择各种产品,将它们放入购物卡中......并点击“订单”按钮时,订单就存在了。

想想“现实”世界中的事物是怎样的。这就是应该指导您构建的模型的内容。

含义:您的产品不应子类化订单。相反,您可以这样做:

public abstract class ShopItem {
  // that contains those things that all products in the shop have in common, like
  public abstract double getPrice();

...

然后您的所有产品都扩展了该类。在这里完全避免继承可能更有用,并将 ShopItem 变成 interface (这取决于您是否真的找到使用抽象类的充分理由;为了定义 common ShopItems 的行为)。

下一步:

public class ProductOrder {
  private final ShopItem orderedItem ...
  private final int quantity ...

把东西放在一起:

public final class Order {
  private final List<ProductOrder> allItemsOfAnOrder ...

【讨论】:

  • 不知道你从哪里得到最后一部分,因为问题中没有类似的东西,而且可能不仅仅是他赌博的目的。 List&lt;Order&gt; 足以添加任何扩展 Order 的对象。通过将其设为List&lt;? extends Order&gt;,这仅意味着您可以将实际的List 实现分配给使用扩展Order 的泛型的变量。但除了从外部传入的集合之外,我会质疑它的用处。
【解决方案2】:

您的方法签名将是:

public void add(Order order){
...
}

因为 Order 可以持有对其任何子类型的引用。

【讨论】:

  • 请不要只是复制和粘贴 cmets。至少解释一下它为什么起作用。
  • 父类不持有对其子类型的引用
  • @Federico 请解释一下?
【解决方案3】:

我真的不认为你需要自己的OrderList。由于Order 是一个抽象类,您只能将非抽象子类的实例添加到您声明的任何List&lt;Order&gt;

还有,而不是

class OrderList {
    private ArrayList<Order> list;

    public OrderList() {
        list = new ArrayList<Order>();
    }
}

你也可以使用

class OrderList extends ArrayList<Order> {

    public OrderList() {
        super();
    }
}

然后只需使用您从父类继承的add(Order element)

但话又说回来,在您打算使用OrderList 的任何地方声明ArrayList&lt;Order&gt; 可能会更方便,只要您不添加任何新方法(常规@987654329 没有给出) @) 来证明有一个额外的课程是合理的。

【讨论】:

    猜你喜欢
    • 2016-07-11
    • 1970-01-01
    • 1970-01-01
    • 2016-07-27
    • 1970-01-01
    • 2013-11-12
    • 2015-10-08
    • 2011-08-31
    • 1970-01-01
    相关资源
    最近更新 更多