工厂中的Java泛型/枚举



我一直在学习Java,想知道如何实现这样的产品工厂的想法吗?(或其他方式的代码结构(

public interface  VirtualBD <E extends Enum<E>>  {  
void addInStorage(Class<E> type, Product product, int amount);
}

1问题:如何使用泛型获得任何类型的Enum类作为参数

根类别

public abstract class Product { 
...
}
public enum AlchogolType {
Beer, Vodka;
}
public enum nonAlchogolType {
FreshJuise, Lemonade;
}

子类别

public abstract class Alchogol extends Product {
...
}
public abstract class nonAlchogol extends Product {
...
}
public class Beer extends Alchogol {
...
}

而且,这里有一个问题开始:

public class AlchogolTables implements VirtualBD{
HashMap<Alchogol, Integer> beer = new HashMap<Alchogol, Integer>();
HashMap<Alchogol, Integer> vodka = new HashMap<Alchogol, Integer>();
@Override
public void addInStorage(AlchogolType type, Product product, int amount) {
switch (type) {
case Beer:
beer.put((Alchogol) product,amount);
break;
case Vodka:
vodka.put((Alchogol) product,amount);
break;

default:
break;
}

}
}

在我的想法中,我想对不同的产品使用addInStorage方法,比如:

public class OtherBeveragesTables implements VirtualBD{
HashMap<nonAlchogol, Integer> orangeFresh = new HashMap<nonAlchogol, Integer>();
HashMap<nonAlchogol, Integer> soda = new HashMap<nonAlchogol, Integer>();
@Override
public void addInStorage(nonAlchogolType type, Product product, int amount) {
switch (type) {
case FreshJuise:
orangeFresh.put((nonAlchogol) product,amount);
break;
case Lemonade:
soda.put((nonAlchogol) product,amount);
break;

default:
break;
}

}
}
  1. 如何使用Enum AlchogolType/nonAlchogolType作为参数
  2. 我怀疑这样一项任务的代码组织的正确性:为许多具有类别、一些差异和相似性的产品编写工厂
  3. 是一种CAST:啤酒。放入((Alchogor(产品,量(正常方式

问题1

";如何使用Enum AlchogolType/nonAlchogolType作为参数">

在阅读您的问题时,我假设您正在寻找一种方法,如何在同一方法中同时传递AlchogolType和NonAlchogolType作为参数。不幸的是,这是不可能的,因为方法要求特定的类型。与类不同,枚举不能从其他类/枚举重写。这意味着方法中给定的参数类型不能是其他类型。

假设有EnumOne(苹果、香蕉、松果(和EnumTwo(奥迪、宝马、福特(。如果一个方法要求EnumOne类型的参数,则无法传递EnumOne枚举中未定义的任何其他参数。在尝试传递来自EnumTwo的值时,您会遇到编译器错误。

如果你想解决这个问题,你可以试着把这些值放在一个枚举类中。只有当您的代码仍然可以保持可维护性和高效性时,才能执行此操作。

问题2

";我怀疑这样一项任务的代码组织的正确性:为许多具有类别、一些差异和相似性的产品编写工厂">

即使您在代码中使用抽象来从模型中划分逻辑,您仍然使用单独的类(在您的情况下是VirtualDB类(,这会阻止您的程序在面向对象编程中使用抽象的好处。

在模型类中使用抽象(在您的例子中是Beer(是很好的。我建议保持这种状态,不要将抽象与工厂类结合使用。

我相信你只需要一个工厂级就可以容纳你所有的产品。你可以为每种类型的饮料制作一个HashMap,但这使得你在制作新类型的饮料时总是必须更新你的工厂类。您可以做的是制作一个键为Product、值为Integer的HashMap,然后将饮料类型的枚举保存在Product类中。原因是饮料的种类是产品的特性。现在,判断饮料类型的唯一方法是知道它保存在什么HashMap中。考虑到稍后在代码中您可能可以访问Product实例,而无法访问工厂中的HashMap,这似乎效率很低。当在Product实例本身中保存饮料类型时,您可以创建一个返回饮料类型的方法。

问题3

";是一种CAST:啤酒。放入((Alchogor(产品,量(;正常方式">

这是否可以,实际上取决于你之前做了什么。这一切都与";狗是一种动物,但动物并不总是狗;故事

假设您有一个抽象类Animal和两个类DogCat,它们都继承自Animal类。如果您有一个Animal继承类的实例,要将其强制转换为Dog,并且之前没有检查该实例是否真的是狗,那么您要求抛出错误。实例可以Dog类的实例,但也可以是Cat类的实例。如果您尝试将其强制转换为错误的继承类型,则会得到java.lang.ClassCastException.

若要解决可能引发此错误的情况,请始终事先检查要尝试强制转换的变量是否属于特定的继承类型。您应该查看instanceof关键字。

仅供参考,如果您没有事先检查变量,那么当您尝试强制转换变量时,现代IDE在大多数情况下都会向您发出警告。


我的主要语言不是英语。我尽力解释。如果你确实有评论或任何你想让我知道的事情,请随时编辑我的评论或在下面放一条评论。

最新更新