微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

工厂中的 Java 泛型/枚举

如何解决工厂中的 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;
        }
        
    }

}
  1. 如何使用 Enum AlchogolType/nonAlchogolType 作为参数?
  2. 对于以下任务,我怀疑代码组织的正确性:为许多具有类别、一些差异和相似之处的产品编写工厂。
  3. 是 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 和两个类 DogCat,它们都继承自 Animal 类。如果您有一个 Animal 继承类的实例想要转换为 Dog 并且您之前没有检查此实例是否实际上是一只狗,那么您是在要求抛出错误。实例可以Dog 类的实例,但也可以是 Cat 类的实例。如果您尝试对其进行强制转换并且将其强制转换为错误的继承类型,则会得到一个 java.lang.ClassCastException

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

仅供参考,如果您没有事先检查,现代 IDE 会在您尝试强制转换变量时向您发出警告。


我的主要语言不是英语。我试图尽我所能解释它。如果您有任何评论或任何想让我知道的内容,请随时编辑我的评论或在评论下方添加评论。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。