簡體   English   中英

通用方法(有界類型)與 inheritance

[英]Generic method (bounded type) vs inheritance

我有一個典型的問題,什么更好,我認為答案總是取決於它,但我還是想澄清一下。 所以有兩種方法:

public static <A extends Animal, F extends Food> void feed(A animal, F food) {
    animal.setFood(food);
}

public static void feed(Animal animal, Food food) {
    animal.setFood(food);
}

和邏輯:

Cat cat = new Cat(); // Cat is a child of Animal
Dog dog = new Dog(); // Dog is a child of Animal

Pork pork = new Pork(); // Pork is a child of Food
pork.setName("Whiskas");
Beef beef = new Beef(); // Beef is a child of Food
beef.setName("Pedigree");

AnimalService.feed(cat, beef);
AnimalService.feed(dog, pork);

cat.eat(); // prints I'm eating Pedigree
dog.eat(); // prints I'm eating Whiskas

我知道由於類型擦除導致方法簽名沖突,所以我的問題不是“為什么我不能同時擁有這兩種方法?”,而是“你會選擇哪種方法?”。

正如你所說,這取決於。 您需要記住 generics 是一個編譯時工具,可幫助編譯器進行一些檢查並在您違反約束時吐出錯誤。

在您的情況下,除了參數類型( AnimalFood )的上限之外,您似乎沒有任何限制要違反,因此您不會從使用 generics 中獲得任何收益 - 因此我會選擇基於普通 inheritance 的方法。

但是,考慮您正在更改Animal接口以定義動物需要的食物種類(因此添加了 inheritance 無法幫助您在編譯時強制執行的約束):

interface Animal<F extends Food> { ... }

class DogFood implements Food { ... }
class CatFood implements Food { ... }
class Whiskas extends CatFood { ... }

class Dog implements Animal<DogFood> { ... }
class Cat implements Animal<CatFood> { ... }

現在feed()可以使用 generics 讓編譯器幫助您選擇正確的食物類型:

<F extends Food> void feed(Animal<F> animal, F food) { ... }

//this should compile because Cat defines Food needs to be CatFood
feed(new Cat(), new CatFood());

//this should also compile because Whiskas is CatFood
feed(new Cat(), new Whiskas());

//this shouldn't compile because DogFood is not CatFood
feed(new Cat(), new DogFood());

暫無
暫無

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

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