Java中的泛型还是继承/接口?

Java中的泛型还是继承/接口?,java,generics,Java,Generics,还有第三种方法,我个人会选择: class Product{ String name; Category category; } interface Category { String type(); } class C1 implements Category{ ... @Override String type(){ ... } } class C2 implements Category{ ... @Overri

还有第三种方法,我个人会选择:

class Product{
  String name;
  Category category;
}

interface Category {
   String type();
}

class C1 implements Category{
    ...
   @Override
   String type(){
      ...   
   }
}

class C2 implements Category{
    ...
   @Override
   String type(){
      ...   
   }
}
我建议这样做的原因是,你可能会有不同类型的产品,例如衬衫、牛仔裤、内衣、一瓶牛奶。它们可能与
产品有
关系,即衬衫是产品,一瓶牛奶是产品。这表示
Shirt
将从某个基本
产品
类继承:

interface Product
{
    public String getName();
    public String getCategory();
}

class Shirt implements Product
{
    @Override
    public String getName()
    {
        return "Shirt";
    }

    @Override
    public String getCategory()
    {
        return "Clothing";
    }
}
或者,它将实现一个
产品
接口:

class Product
{
    String name;
    String category;
}
这两种方法都可以,我更喜欢这个界面,因为它不会把你限制在单亲家庭。现在,每种产品都可以有更具体的属性——例如,一件衬衫会有一个尺寸,而一瓶牛奶会有一定的体积:

interface Product
{
    public String getName();
    public String getCategory();
}
哪一个更好?在不同的情况下如何选择哪一个

在编码方面,要证明一种解决方案比另一种更好,即使不是不可能,也是相当困难的。这是一个你必须做出的判断,你会随着经验而变得更好。也就是说,有两件事你应该经常考虑:

  • 这个解决方案使用起来有多容易
  • 维护此解决方案有多容易
开始实施一个解决方案的小模型,亲自看看哪一个效果更好。实例化一个产品容易吗?还是对类进行单元测试?3个月后,当你决定添加新产品时,情况如何


我希望这对您将来有所帮助。

在重新阅读了这个问题后,我想我更了解您的要求-您如何决定是使成员通用,还是使用接口?我会留下我的第一个答案,以防你觉得它有一定的相关性,但这里有一个更具体的答案

假设我有一个“Order”类,它包含一个产品和要购买的数量

class MilkBottle implements Product
{
    int volume;

    @Override
    public String getName()
    {
        return "Milk (" + volume + "ml)";
    }

    @Override
    public String getCategory()
    {
        return "Grocery";
    }
}
如果我将其改为
Order
类的泛型参数,会发生什么

class Order
{
    Product product;
    int quantity;
}
现在,这两种解决方案在实现目标方面几乎是相同的
GenericOrder
比普通的老式
Order
灵活一点,因为您可以使用一种只接受鞋子订单的方法:

class GenericOrder<P extends Product>
{
    P product;
    int quantity;
}

如果您不需要对特定类型的订单执行操作,为了简单起见,我建议使用
Order
类型。如果在将来的某个时候,您发现自己需要通用版本的功能,那么在IDE中重构通用版本并不难。

它们可以做不同的事情。泛型版本指定的组件类型不受类型限制。继承版本指定特定的类型。没有限制和特定类型是完全不同的。不需要限制组件类型时,请使用“无限制”。需要特定类型时请使用特定类型。“Java中的泛型或继承/接口?”。。。是的。您应该在第一个示例中添加一个限制:
类产品
。这样,设计方法就可以定义编译时限制(“我只想要X类产品”):
public-void-anyMethod(产品如果您需要从
产品
中获得
C2
,则首选通用版本。第二个版本只能为您提供一个
类别
。如果这或类似内容不是一个要求,请尝试第二个非通用解决方案,以简化操作。“在未来,……重构它并不难"一旦发布了API,即客户端代码正在使用它,如果更改代码使用的内容,则很难对其进行重构。使类型泛型会突然导致现有代码中断,并出现未经检查的警告。必须修改现有代码以采用这些更改。在提交API之前,请仔细考虑。是否可以这样定义:类 GenericOrder@user697911当你使用问号时,它基本上意味着“我不在乎这是什么类型,因为我不会直接引用它”。这使得它在类声明中毫无意义,因为你不能有特定类型的变量。当你使用类型时,它更有用。在最后一个示例中,above、
一般订单
可以替换为
GenericOrder@LewBloch是的,如果您计划将该类作为API的一部分发布,我更倾向于从通用版本开始,这样最终用户在需要时可以有更多的灵活性。任何其他类型使用的任何类型都是API。这很好。我终于想出了一个解决方案在这种情况下,我花了几个小时试图用泛型来解决我的问题。似乎泛型涉及到更多的复杂性。
class GenericOrder<P>
{
    P product;
    int quantity;
}
class GenericOrder<P extends Product>
{
    P product;
    int quantity;
}
public int availableShoeBoxes(GenericOrder<Shoe> order)
{
    ...
GenericOrder<Shirt> order = new GenericOrder<>(shirt, quantity);