用Java绑定多个类

时间:2019-06-16 19:45:43

标签: java generics bounding

我正在做一个分配,要求我创建两个类的两个类的通用集合(称为ComputerOrder和PartyTrayOrder):ComputerPart,Peripheral和Service,以及分别为Cheese,Fruit和Service。所有这些类(ComputerPart,Fruit,Service等)都扩展了一个称为Product的类。

我遇到的问题是,用Java绑定多个类似乎是不可能的,因为您可能只绑定了多个接口,并且不允许修改现有的类结构。

我已经阅读并看到它建议我创建和接口“编码”所有相关的类,但是我看不到没有ComputerPart,Peripheral等也可以作为接口然后使用扩展关键字。我已经看到它进一步建议我创建名为ComputerProduct和PartyTrayProduct的抽象类,但是我看不到它将如何以任何方式限制类型。

我不允许发布图片,但这是一个 class diagram, including some unrelated assignment objects

这是我当前的ComputerOrder代码,尽管它仅限制父类产品,这实际上并不是赋值指定的结果。

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

以下是作业规范:

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

  2. 设计并实现GenericOrder的子类,称为ComputerOrder,该子类接受任意数量的不同类的ComputerPart对象,外围对象和Service对象。实施尽可能多的方法。

  3. 设计并实现GenericOrder的子类PartyTrayOrder,该子类采用任意数量的不同类的Cheese对象,Fruit对象和Service对象。实施尽可能多的方法。 (...)

2 个答案:

答案 0 :(得分:1)

这是我想出的唯一解决方案,它遵循字母的赋值,并且仍然有意义(即使我认为这不是一个“好的”解决方案-请参阅注释以下):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());

    }
}

我认为这是预期的解决方案,因为分配包含广泛的提示:

  

实施尽可能多的方法。

最有可能的目标是实施一个神奇地绑定到多个类的 one 方法。相反,必须为每个“类别”添加一种方法。


另外:我的直觉是可以改进此设计。试想一下,您必须为新的订单类型创建类CarOrderFahsionOrder等。或者想象PartyTrayOrder必须扩展为还处理MeatDipSalad之类的类:您最终将获得带有许多专门方法的数十个类。

通过引入专门与“特定订单类型”可接受的类型“完全匹配”的专用“产品类型”,可以避免上述情况。因此,我认为(Product应该是一个 interface 开头,并且)应该像{p1}中那样存在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的必需范围进行了建模。这样的好处是:您不再需要ComputerOrderPartyTrayOrder类!这样GenericOrder可以是非抽象的,并且创建您将要正确使用通用类型绑定的特定订单类型。

这是一个完整的示例,其中我只是将Salad作为一种新的PartyTrayProductCarPart作为一种新类型的产品,而不必扩展或修改任何基础设施类别”:

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());
    }
}

答案 1 :(得分:0)

该图准确地显示了类层次结构的外观。每个粗箭头都是类的扩展。当箭头从A指向B时,意味着A扩展了B。您只需要将其关闭为Java代码即可。

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