我正在做一个作业,需要我创建几个类的两个通用集合(称为ComputerOrder和PartyTrayOrder):ComputerPart,Peripheral和Service,以及奶酪,水果和服务。所有这些类(ComputerPart,Fruit,Service等)都扩展了一个名为Product的类。
我遇到的问题是,在 Java 中似乎不可能绑定多个类,因为您可能只绑定多个接口,并且不允许修改现有的类结构。
我已经阅读并看到它建议我创建和接口"编码"所有相关类,但我看不出如果没有 ComputerPart、外围设备等也是接口然后使用 extend 关键字,这怎么可能。我已经看到它进一步建议我创建名为ComputerProduct和PartyTrayProduct的抽象类,但我看不出这将如何以任何方式限制类型。
我不允许发布图片,但这里有一个 类图,包括一些不相关的赋值对象
这是我当前的 ComputerOrder 代码,尽管它只绑定父类产品,这意味着它并不像赋值指定的那样。
public class ComputerOrder<T extends Product> extends GenericOrder<T> {
public ComputerOrder() {
super();
}
}
以下是分配规范:
设计并实现一个名为 GenericOrder 的通用容器,该容器充当 Products.java 中任意数量的对象的集合。设计一种机制,为容器的每个实例提供一个唯一标识符。您必须使用 Java 泛型功能。
设计并实现一个名为 ComputerOrder 的 GenericOrder 子类,该子类采用任意数量的不同类的 ComputerPart 对象、外围设备对象和服务对象。根据需要实现尽可能多的方法。
设计并实现一个名为 PartyTrayOrder 的 GenericOrder 子类,该子类采用任意数量的不同类的 Cheese 对象、Fruit 对象和服务对象。根据需要实现尽可能多的方法。 (...)
这是我提出的唯一解决方案,它遵循字母的赋值并且仍然有意义(即使我认为这不是一个"好"的解决方案 - 请参阅下面的注释):ComputerOrder
和PartyTrayOrder
可以提供仅接受特殊类型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());
}
}
我假设这是预期的解决方案,因为赋值包含广泛的提示:
根据需要实现尽可能多的方法。
因此,最有可能的是,目标不是实现一个神奇地限制在多个类的方法。相反,必须为每个"类别"添加一个方法。
题外话:我的直觉是这个设计可以改进。想象一下,您必须为新类型的订单创建类CarOrder
和FahsionOrder
等。或者想象一下,PartyTrayOrder
必须扩展以处理Meat
、Dip
或Salad
等类:你最终会得到几十个类和几十个专门的方法。
通过引入与特定"订单类型"可接受的类型完全匹配的专用"产品类型",所有这些都可以避免。所以我认为(Product
应该首先是一个接口,并且)应该有像ComputerProduct
和PartyTrayProduct
这样的接口,如
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 {}
这样,特定ComputerOrder
和PartyTrayOrder
所需的边界就已经使用类层次结构建模。这样做的好处是:您不再需要ComputerOrder
和PartyTrayOrder
课程!然后,GenericOrder
可以是非抽象的,为了创建特定类型的订单,您只需正确使用通用类型绑定即可。
下面是一个完整的示例,我刚刚将Salad
作为新PartyTrayProduct
,CarPart
作为新型产品,而无需扩展或修改任何"基础结构类":
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());
}
}
该图准确地显示了类层次结构的外观。每个胖箭头都是一个类扩展。当箭头从 A 指向 B 时,表示 A 扩展了 B。你只需要把它关闭到java代码中。
当 A 扩展 B 并且 B 扩展 C 时,A 是 C。我认为这里不需要多碱基继承。