red*_*der 4 java generics extends programming-languages abstract
我正在从DotNet转向java,这种扩展的想法是新的.
我已经看到一些帖子完全解释了使用List<? extends SomeAbstract>vs. List<? super SomeAbstract>vs. List<SomeAbstract>,但我猜测在泛型中使用和不使用扩展之间没有区别.
真的吗?如果使用抽象类作为父级,答案会改变吗?
class My_AbstractExtends<T extends SomeAbstract>
Run Code Online (Sandbox Code Playgroud)
与
class My_Abstract<SomeAbstract>
Run Code Online (Sandbox Code Playgroud)
按如下方式创建子类
class My_ChildExtends extends My_AbstractExtends<ConcreteChildOfSomeAbstract>
Run Code Online (Sandbox Code Playgroud)
与
class My_Child extends My_Abstract<ConcreteChildOfSomeAbstract>
Run Code Online (Sandbox Code Playgroud)
我猜你在谈论在类型参数声明中使用extends.在这种情况下:
class My_Abstract<T extends SomeAbstract>
Run Code Online (Sandbox Code Playgroud)
有一个有界类型参数T,必须是SomeAbstract它的一个子类型.
class My_Abstract<SomeAbstract>
Run Code Online (Sandbox Code Playgroud)
有一个无限的类型参数SomeAbstract,可以是任何东西.请注意,SomeAbstract不再引用SomeAbstract第一个示例使用的实际类型!
为此扩展:想象一下如果是第二个声明class My_Abstract<T>.在T那里显然是一个类型参数,而不是实际的类型.但它并没有被称为T......那才叫E或Bob或SomeAbstract.在所有这些情况下,它仍然只是一个类型参数...实际类型永远不会去那里,它也没有任何意义(类型参数的整个点是不引用特定类型,但而是在创建类的实例时允许其他类型放在其位置).
在您编辑的代码中,将My_Child声明更改为
class My_Child extends My_Abstract<Object>
Run Code Online (Sandbox Code Playgroud)
你会看到差异.如果您实际上尝试使用SomeAbstract第二个版本中的type参数执行某些操作,您还会发现无法调用真实SomeAbstract类中声明的任何方法.这就是为什么你应该总是遵循使用单字母类型参数的惯例的一个很好的例子...如果你不这样做,那真是令人困惑.
这个问题变得非常漫长,但我还想指出,所有这些与你问题的前半部分基本无关.像通配符? extends SomeAbstract和? super SomeAbstract未在类型参数声明(如那些定义一个通用类时使用)使用,他们主要用于方法参数.List是一个典型的例子,用于解释为什么需要通配符,因为它作为对象容器的性质使它相对容易理解,但与它们相关的规则适用于任何泛型类型.我试着在这个答案中以相对笼统的方式解释这一点.