簡體   English   中英

Java中的泛型還是繼承/接口?

[英]Generics or inheritance/Interface in Java?

class Product<T>{
   String name;

   T category;
}

與下面的設計相比,哪種更好,如何在不同情況下選擇哪種? 我覺得它們在功能上是相同或非常相似的。

class Product{
  String name;
  Category category;
}

interface Category {
   String type();
}

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

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

您可以采用第三種方式,我個人會選擇:

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

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

    @Override
    public String getCategory()
    {
        return "Clothing";
    }
}

我建議采用這種方式的原因是,您可能會選擇不同類型的產品,例如襯衫,牛仔褲,內衣和一瓶牛奶。 這些可能與Product is a關系,即襯衫是產品,一瓶牛奶是產品。 這表明Shirt將繼承某些基本Product類:

class Product
{
    String name;
    String category;
}

或者,它將實現一個Product接口:

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

兩種方法都可以使用,我更喜歡該界面,因為它不會將您限制為單親。 現在,每種產品也可以具有更具體的屬性-例如,襯衫將具有尺寸,而一瓶牛奶將具有一定體積:

class MilkBottle implements Product
{
    int volume;

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

    @Override
    public String getCategory()
    {
        return "Grocery";
    }
}

哪個更好,如何在不同情況下選擇哪個?

要證明一種解決方案優於另一種解決方案,即使不是不可能,也很難。 這是一個必須作出的判斷,經驗會變得更好。 話雖如此,您應該始終考慮兩件事:

  • 使用該解決方案有多容易?
  • 該解決方案的維護難度如何?

開始實施您的解決方案的小模型,然后親自查看您認為哪種方案更好。 實例化產品容易嗎? 還是要對課程進行單元測試? 3個月后,當您決定添加新產品時呢?

希望以后對您有所幫助。

重新閱讀問題后,我想我會更好地理解您的要求-您如何決定是使成員成為通用成員還是使用接口? 如果您覺得它有一定的相關性,我將保留第一個答案,但這是一個更具體的答案。

假設我有一個“訂單”類,其中包含產品和要購買的數量。

class Order
{
    Product product;
    int quantity;
}

如果我改用Order類的通用參數會怎樣?

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

正如@rollback在評論中指出的那樣, product可以是任何東西! 它可以是Shirt ,也可以是int 我們唯一可以保證的類型P是它繼承自Object 我們需要添加一些約束,以便P必須是某個繼承自(或實現) Product

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

現在,這兩種解決方案在實現目標方面幾乎是相同的。 GenericOrder比普通的Order更靈活,因為您可以有一個只接受鞋子訂購的方法:

public int availableShoeBoxes(GenericOrder<Shoe> order)
{
    ...

您只是不能使用簡單的舊Order來做到這一點,因此,如果您(或使用代碼的其他任何人)需要該用例,則應使用通用類型。

GenericOrder一個缺點是,每次要使用它時,都必須指定P類型:

GenericOrder<Shirt> order = new GenericOrder<>(shirt, quantity);

如果您不需要對特定類型的訂單進行操作,為簡單起見,我建議您使用Order類型。 如果將來某個時候您發現自己需要通用版本的功能,那么在IDE中重構它就不難了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM