当前位置: 首页 > 知识库问答 >
问题:

泛型方法(有界类型)与继承[关闭]

高豪
2023-03-14

我有一个典型的问题,什么是更好的,我认为答案总是视情况而定,但我还是想澄清一下。所以有两种方法:

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

我知道由于类型擦除,方法签名存在冲突,所以我的问题不是“为什么我不能同时拥有这两个方法?”,而是“你会选择哪种方法?”。

共有1个答案

太叔鸿博
2023-03-14

正如你所说,这要看情况而定。您需要记住,泛型是一种编译时工具,可以帮助编译器进行一些检查,并在违反约束时抛出错误。

在您的例子中,除了参数类型的上限(AnimalFood)之外,您似乎没有任何要违反的约束,因此您不会从使用泛型中获得任何好处-因此我选择基于简单继承的方法

然而,考虑你正在改变你的<代码>动物< /代码>界面,以定义动物需要的食物种类(从而增加了一个约束,即继承不能帮助你在编译时执行):

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()可以使用泛型让编译器帮助您选择正确的食物类型:

<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());
 类似资料:
  • 我有一个典型的问题,什么是更好的,我认为答案总是视情况而定,但我还是想澄清一下。所以有两种方法: 逻辑是: 我知道由于类型擦除,方法签名存在冲突,所以我的问题不是“为什么我不能同时拥有这两个方法?”,而是“你会选择哪种方法?”。

  • 和这个问题相关的课程: 现在,这似乎已被编译器接受。不幸的是,我不知道/理解如何创建的新实例,。 当然,这确实不起作用:

  • 在了解Java泛型的过程中,我遇到了以下问题: 假设我有下面的方法来添加列表的元素,只限于包含数字的列表。 但是这段代码和这段代码有什么不同: 它们都按预期编译和执行。这两者之间有什么区别?除了语法之外?什么时候我更喜欢使用通配符而不是前者? 是的,使用通配符方法,我不能在列表中添加除null之外的新元素,否则它将无法编译。除此之外呢?

  • 我在抽象课上有以下内容... 还有另一个类,它继承了这个类... 当我从主类执行以下调用时,我收到一个错误... 我的问题是..为什么会发生这种情况?我的getEntityById不是返回T型的东西,在这种情况下应该是产品吗? 我在 Netbeans 中工作,编译时未显示任何错误。 感谢您的帮助=)

  • 例如,我有以下接口 实现此接口的抽象类 以及具体实施 我想建议所有将转换为任何内容的方法。我创建了以下方面 这是行不通的。Spring不会为类创建代理。然而,如果我从抽象类重写方法,它将开始工作,Spring成功地为创建代理,并执行所有需要的逻辑。 为什么会发生这种情况?有没有办法定义切入点,这样我就不需要重写方法?

  • 问题内容: 我有三节课: 现在在我的主要职能中,我做这样的事情: 但这会产生2个编译时错误: 无法将A转换为fileHandler 无法将B转换为fileHandler 如果基类不是泛型的,那么我如何摆脱这些错误呢? 更新: 我的班级层次结构是: 调用函数的C类或 调用函数的D类。 C和D都从抽象类E派生。 现在,我应该如何在C和D以及E中定义这些功能: 我给出了以下内容: E: C: D: C,