我对Java泛型如何处理继承/多态性感到困惑.
假设以下层次结构 -
动物(父母)
狗 - 猫(儿童)
所以假设我有一个方法doSomething(List<Animal> animals).根据所有继承和多态的规则,我会假设a List<Dog> 是 a List<Animal>而a List<Cat> 是 a List<Animal>- 所以任何一个都可以传递给这个方法.不是这样.如果我想实现这种行为,我必须明确告诉该方法接受一个Animal的任何子类的列表doSomething(List<? extends Animal> animals).
我知道这是Java的行为.我的问题是为什么?为什么多态通常是隐含的,但是当涉及泛型时必须指定它?
我在阅读泛型时遇到了PECS(制片extends人和消费者的super简称).
能否给我一个人解释如何使用佩奇之间解决困惑extends和super?
我真的很难理解外卡参数.我有几个问题.
?作为类型参数只能在方法中使用.例如:printAll(MyList<? extends Serializable>)我无法使用?类型参数定义类.
我理解上限?. printAll(MyList<? extends Serializable>)意思是:" 如果它有实现接口的对象,printAll将打印.MyListSerialzable "
我有一个问题super.printAll(MyList<? super MyClass>)意思是:" 如果它有对象或任何扩展的类(后代),printAll将打印.MyListMyClassMyClassMyClass "
在我出错的地方纠正我.
总之,只有T或E或K或V或N可以用作类型参数用于定义通用类.?只能用于方法
public void printAll(MyList<? super MyClass>){
// code code code
}
Run Code Online (Sandbox Code Playgroud)
根据Ivor Horton的书,MyList<? super MyClass>意味着MyList如果它具有MyClass它实现的对象或任何接口或类,我可以打印.也就是说,MyClass是一个下限 …
所以我查看了一些Java代码并偶然发现:
List<? extends SomeObject> l;
Run Code Online (Sandbox Code Playgroud)
基本上这个列表接受SomeObject的某些对象 - SomeObject本身或其继承者.但是根据多态性,它的继承者也可以像SomeObject一样,所以这也可以:
List<SomeObject> l;
Run Code Online (Sandbox Code Playgroud)
那么,当第二个选项明确定义并且几乎相同时,为什么有人会使用第一个选项?