如何解决工厂中的 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,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,int amount) {
switch (type) {
case FreshJuise:
orangeFresh.put((nonAlchogol) product,amount);
break;
case Lemonade:
soda.put((nonAlchogol) product,amount);
break;
default:
break;
}
}
}
- 如何使用 Enum AlchogolType/nonAlchogolType 作为参数?
- 对于以下任务,我怀疑代码组织的正确性:为许多具有类别、一些差异和相似之处的产品编写工厂。
- 是 CAST:beer.put((Alchogol) product,amount); 正常方式吗?
解决方法
问题 1
“我如何使用 Enum AlchogolType/nonAlchogolType 作为参数?”
在阅读您的问题时,我假设您正在寻找一种方法,如何在同一方法中将 AlchogolType 和 NonAlchogolType 作为参数传递。不幸的是,这是不可能的,因为方法要求特定类型。与类不同,枚举不能被其他类/枚举覆盖。这意味着方法中给出的参数类型不能是其他任何东西。
假设有 EnumOne
(苹果、香蕉、菠萝)和 EnumTwo
(奥迪、BWM、福特)。如果一个方法要求类型为 EnumOne
的参数,则无法传递 EnumOne
枚举中未定义的任何其他内容。尝试从 EnumTwo
传递值时,您会遇到编译器错误。
如果你想解决这个问题,你可以尝试将这些值放在一个枚举类中。只有在您的代码仍然可以保持可维护性和高效性时才这样做。
问题 2
“我怀疑代码组织的正确性,例如:为许多具有类别的产品编写工厂,但存在一些差异和相似之处。”
即使您在代码中使用抽象将逻辑与模型分开,您仍然使用单独的类(在您的情况下为 VirtualDB 类),这会阻止您的程序在面向对象编程中使用抽象的好处。
在您的模型类(在您的情况下为 Beer)中使用抽象是好的。我建议保持这种状态,不要进一步将抽象与工厂类结合起来。
我相信您只需要 1 个包含所有产品的工厂类。您可以为每种类型的饮料制作一个 HashMap,但这使得您在制作新类型的饮料时始终必须更新工厂类。您可以做的是使用作为键 Product
和作为值 Integer
的单个 HashMap,然后将饮料类型的枚举保存在 Product
类中。原因是因为饮料的类型是产品的属性。现在,判断饮料类型的唯一方法是知道它保存在哪个 HashMap 中。考虑到稍后在您的代码中您可能可以访问 Product 实例,而无法访问工厂中的 HashMap,这似乎效率很低。在 Product 实例本身中保存饮料类型时,您可以创建一个返回饮料类型的方法,仅此而已。
问题 3
“是一个 CAST:beer.put((Alchogol) product,amount); 正常方式吗?”
这是否可行实际上取决于您事先做了什么。这一切都与“狗是动物,但动物并不总是狗”的故事有关。
假设您有一个抽象类 Animal
和两个类 Dog
和 Cat
,它们都继承自 Animal
类。如果您有一个 Animal
继承类的实例想要转换为 Dog
并且您之前没有检查此实例是否实际上是一只狗,那么您是在要求抛出错误。实例可以是 Dog
类的实例,但也可以是 Cat
类的实例。如果您尝试对其进行强制转换并且将其强制转换为错误的继承类型,则会得到一个 java.lang.ClassCastException。
要解决可能引发此错误的可能情况,请始终事先检查您尝试强制转换的变量是否属于特定的继承类型。您应该看看 instanceof 关键字。
仅供参考,如果您没有事先检查,现代 IDE 会在您尝试强制转换变量时向您发出警告。
我的主要语言不是英语。我试图尽我所能解释它。如果您有任何评论或任何想让我知道的内容,请随时编辑我的评论或在评论下方添加评论。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。