假设我有抽象类(或者实际上是接口)
public abstract class Animal
public abstract class Bird Extends Animal
和通用类
public class Lifestyle<A extends Animal>
因此我们可以创建一个Lifestyle<Lion>
对象。
Lifestyle
类包含动物可以用来告诉他们如何四处走动,寻找食物,与同一物种的其他动物互动等的方法。现在假设我想将这个类扩展为特殊的{ {1}}类告诉BirdLifestyle
如何执行上述所有操作,同时告诉他们如何Bird
并使用fly
类中的所有额外方法。我希望能够创建一个Bird
对象。我很确定以下内容无法编译:
BirdLifestyle<Eagle>
,我能想到的唯一选择是相当讨厌:
public class BirdLifestyle<B extends Bird> extends Lifestyle<A extends Animal>
然后我们可以通过调用public class BirdLifestyle<B extends Bird>
{
private Lifestyle<B> lifestyle // tells the bird how to do animal things.
public Lifestyle<B> getLifestyle()
{
return lifestyle;
}
// Bird-specific methods.
}
或类似的东西来获取Animal
中的所有方法。
现在假设我的朋友们已经创建了他们自己的这四个类的实现,并且我们想要使用接口链接它们。所以我们创建
getLifestyle().walk()
我的朋友们都更专业,所以他们都写了类似的东西:
public interface LifestyleInterface
{
public void walk();
// etc.
}
public interface AvianLifestyleInterface extends LifestyleInterface
{
public void fly();
// etc.
}
或
public class LionLifestyle implements LifestyleInterface
虽然我可以写:
public class EagleLifestyle implements AvianLifestyleInterface
但我现在不能写:
public class Lifestyle<A extends Animal> implements LifestyleInterface
即使我的public class BirdLifestyle<B extends Bird> implements AvianLifestyleInterface
类覆盖了BirdLifestyle
中引入的所有方法。这是因为AvianLifestyleInterface
不是BirdLifestyle
的超类。解决这个问题的唯一方法是创建许多入口点方法,例如:
Lifestyle
这似乎是编写不必要的代码量,而且很多代码都以相当机械的方式编写,这打破了几个编程规则。例如,如果我想向public class BirdLifestyle<B extends Bird>
{
private Lifestyle<B> lifestyle;
public Lifestyle<B> getLifestyle()
{
return lifestyle;
}
// 'AvianLifestyleInterface' methods.
@Override
public void fly()
{
// Code for flying.
}
// etc.
// 'LifestyleInterface' methods.
@Override
public void walk()
{
getLifestyle().walk();
}
// etc., creating a similar one-line method for each method in
// 'LifestyleInterface' that is just an entry-point to the same
// method in the 'Lifestyle<A>' object.
}
接口添加任何方法,那么我需要记住在LifestyleInterface
类中添加一个新的单行方法。有更干净的方式吗?
答案 0 :(得分:4)
我有点不清楚你在这里问的是什么,但似乎你的第一次尝试可以通过以下方式轻松解决:
public class BirdLifestyle<B extends Bird> extends Lifestyle<B> {
// ...
}
Lifestyle
已经被声明为通用的Lifestyle<A extends Animal>
,不需要重复泛型类型绑定(正如你所说,它不会编译)。
类似地:
public class BirdLifestyle<B extends Bird> extends Lifestyle<B> implements AvianLifestyleInterface {
// ...
}
会工作。
答案 1 :(得分:2)
我现在的问题几乎丢失了。但您肯定可以将BirdLifestyle
课程更改为:
public class BirdLifestyle extends Lifestyle<Bird> { }
不要理解为什么要让BirdLifestyle
本身成为通用类。如果我理解问题的其他部分,我会更新答案。
如果您要转移到界面,那么您可以这样做:
public class BirdLifestyle implements AvianLifestyleInterface { }
同样,为什么要让这个类变得通用?名称BirdLifeStyle
应该真实地描述鸟的生活方式。你有不同种类的Bird
吗?