Java 中的边界倍数 类

Bounding Multiple Classes in Java

我正在做一项作业,要求我创建几个 classes 的两个通用集合(称为 ComputerOrder 和 PartyTrayOrder):ComputerPart、Peripheral 和 Service,以及 Cheese、Fruit、和服务分别。所有这些 class 实体(ComputerPart、Fruit、Service 等)都扩展了一个名为 Product 的 class。

我遇到的问题是在Java中绑定多个class好像是不可能的,因为你只能绑定多个接口,我不允许修改现有 class 结构。

我已经阅读并看到它建议我创建并连接 "codes in" 所有相关的 classes,但我看不出没有 ComputerPart、Peripheral、 etc 也是接口,然后使用 extend 关键字。我看到它进一步建议我创建名为 ComputerProduct 和 PartyTrayProduct 的抽象 classes,但我看不出这将如何以任何方式限制类型。

我不允许post图片,但这里有一个 class diagram, including some unrelated assignment objects

这是我当前的 ComputerOrder 代码,虽然它只限制了父 class 产品,这意味着它并不像分配指定的那样。

public class ComputerOrder<T extends Product> extends GenericOrder<T> {
    public ComputerOrder() {
        super();
    }
}

以下是作业规范:

  1. 设计并实现一个名为 GenericOrder 的通用容器,它充当 Products.java 中任意数量对象的集合。设计一种机制,为容器的每个实例提供唯一标识符。您必须使用 Java 泛型功能。

  2. 设计并实现一个名为 ComputerOrder 的 GenericOrder 的子class,它采用任意数量的不同 class 的 ComputerPart 对象、外围对象和服务对象。根据需要实施尽可能多的方法。

  3. 设计并实现一个名为 PartyTrayOrder 的 GenericOrder 的子class,它采用任意数量的不同 class 奶酪对象、水果对象和服务对象。根据需要实施尽可能多的方法。 (...)

该图向您展示了 class 层次结构的相似之处。每个粗箭头都是 class 的扩展。当箭头从 A 指向 B 时,表示 A 扩展了 B。您只需将其关闭到 java 代码中即可。

当A扩展B,B扩展C时,A是C。我认为这里不需要多基继承。

这是我想出的唯一解决方案,它遵循对字母 的赋值 并且仍然有一定意义(即使我认为它不是 "good" 解决方案 - 请参阅下面的注释):ComputerOrderPartyTrayOrder 可以提供 接受特殊类型 Product 的方法:

abstract class Product {}
class ComputerPart extends Product {}
class Peripheral extends Product { }
class Cheese extends Product {} 
class Fruit extends Product {}
class Service extends Product {} 

abstract class GenericOrder<T extends Product> {
    protected final void addImpl(T t) {
    }
}

class ComputerOrder extends GenericOrder<Product> {
    void add(ComputerPart t) {
        addImpl(t);
    }
    void add(Peripheral t) {
        addImpl(t);
    }
    void add(Service t) {
        addImpl(t);
    }
}

class PartyTrayOrder  extends GenericOrder<Product> {
    void add(Cheese t) {
        addImpl(t);
    }
    void add(Fruit t) {
        addImpl(t);
    }
    void add(Service t) {
        addImpl(t);
    }
}

这样,订单实现可以完全接受正确的类型:

public class ProductExample {

    public static void main(String[] args) {
        ComputerOrder c = new ComputerOrder();
        c.add(new ComputerPart());
        c.add(new Peripheral());
        //c.add(new Cheese()); // Not allowed
        //c.add(new Fruit()); // Not allowed
        c.add(new Service());

        PartyTrayOrder p = new PartyTrayOrder();
        //p.add(new ComputerPart());  // Not allowed
        //p.add(new Peripheral());  // Not allowed
        p.add(new Cheese());
        p.add(new Fruit());
        p.add(new Service());

    }
}

我假设这是预期的解决方案,因为作业包含广泛的提示:

Implement as many methods as necessary.

所以最有可能的是,目标是 而不是 来实现 一个 方法,该方法神奇地限制了多个 classes。相反,必须为每个 "category" 添加一种方法。


旁白:我的直觉是这个设计可以改进。试想一下,您必须为新类型的订单创建 classes CarOrderFahsionOrder 等。或者想象一下 PartyTrayOrder 必须扩展才能处理 class,例如 MeatDipSalad:你最终会得到几十个 classes 有许多专门的方法。

这一切都可以通过引入专用 "product type" 来避免,该 完全 匹配特定 "order type" 可接受的类型。所以我认为(Product 应该是一个 接口 开始,并且)应该有像 ComputerProductPartyTrayProduct 这样的接口,如

interface Product {}

interface ComputerProduct extends Product {}
class ComputerPart implements ComputerProduct  {}
class Peripheral implements ComputerProduct  {}

interface PartyTrayProduct extends Product {}
class Cheese implements PartyTrayProduct{} 
class Fruit implements PartyTrayProduct{}

class Service implements Product {} 
class DeliveryService implements PartyTrayProduct{} 
class AssemblyService implements ComputerProduct  {}

这样,特定 ComputerOrderPartyTrayOrder 所需的边界已经使用 class 层次结构建模。这样的好处是:你不再需要 ComputerOrderPartyTrayOrder class! 然后 GenericOrder 就可以了non-abstract,为了创建特定类型的订单,您只需正确使用绑定的通用类型。

这是一个完整的示例,我刚刚将 Salad 作为新的 PartyTrayProductCarPart 作为新型产品,而无需扩展或修改任何 "infrastructure classes":

interface Product {}

interface ComputerProduct extends Product {}
class ComputerPart implements ComputerProduct  {}
class Peripheral implements ComputerProduct  {}

interface PartyTrayProduct extends Product {}
class Cheese implements PartyTrayProduct{} 
class Fruit implements PartyTrayProduct{}

class Service implements Product {} 
class DeliveryService implements PartyTrayProduct{} 
class AssemblyService implements ComputerProduct  {}

class Salad implements PartyTrayProduct{} // A new PartyTrayProduct

// Entirely new product type:
interface CarProduct extends Product {}
class CarPart implements CarProduct  {}
class CarInterior implements CarProduct  {}

class GenericOrder<T extends Product> {
    public void add(T t) { }
}

public class ProductExample2 {
    public static void main(String[] args) {

        GenericOrder<ComputerProduct> c = new GenericOrder<ComputerProduct>();
        c.add(new ComputerPart());
        c.add(new Peripheral());
        //c.add(new Cheese()); // Not allowed
        //c.add(new Fruit()); // Not allowed
        c.add(new AssemblyService());

        GenericOrder<PartyTrayProduct> p = new GenericOrder<PartyTrayProduct>();
        //p.add(new ComputerPart());  // Not allowed
        //p.add(new Peripheral());  // Not allowed
        p.add(new Cheese());
        p.add(new Fruit());
        p.add(new Salad()); // Just add it...
        p.add(new DeliveryService());

        // Easy to extend:
        GenericOrder<CarProduct> e = new GenericOrder<CarProduct>();
        e.add(new CarPart());
        e.add(new CarInterior());
    }
}