use*_*623 293 java generics syntax design-choices
我想知道Java中是否存在使用always" extends
"而不是" implements
"来定义类型参数边界的特殊原因.
例:
public interface C {}
public class A<B implements C>{}
Run Code Online (Sandbox Code Playgroud)
被禁止但是
public class A<B extends C>{}
Run Code Online (Sandbox Code Playgroud)
是正确的.这是什么原因?
Tet*_*Oni 323
在类'实现'或'扩展'之间的通用约束语言中没有语义差异.约束的可能性是"扩展"和"超级" - 也就是说,这个类是否可以分配给另一个(扩展),或者这个类可以从那个(超级)分配.
Mik*_*elF 67
答案就在这里 :
要声明有界类型参数,请列出类型参数的名称,后跟
extends
关键字,后跟其上限 [...].请注意,在此上下文中,extends在一般意义上用于表示extends
(如在类中)或implements
(在接口中).
所以,你有它,它有点令人困惑,Oracle知道它.
bee*_*tra 17
可能是因为对于双方(B和C),只有类型是相关的,而不是实现.在你的例子中
public class A<B extends C>{}
Run Code Online (Sandbox Code Playgroud)
B也可以是界面."extends"用于定义子接口和子类.
interface IntfSub extends IntfSuper {}
class ClzSub extends ClzSuper {}
Run Code Online (Sandbox Code Playgroud)
我通常认为'Sub extends Super'是' Sub就像Super,但有额外的功能','Clz实现Intf'为' Clz是Intf的实现'.在您的示例中,这将匹配:B类似于C,但具有其他功能.这些功能与此相关,而不是实现.
可能是基类型是通用参数,因此实际类型可以是类的接口.考虑:
class MyGen<T, U extends T> {
Run Code Online (Sandbox Code Playgroud)
此外,从客户端代码角度来看,接口几乎与类无法区分,而对于子类型,它很重要.
我们习惯了
class ClassTypeA implements InterfaceTypeA {}
class ClassTypeB extends ClassTypeA {}
Run Code Online (Sandbox Code Playgroud)
任何对这些规则的轻微偏离都会让我们感到非常困惑。
类型绑定的语法定义为
TypeBound:
extends TypeVariable
extends ClassOrInterfaceType {AdditionalBound}
Run Code Online (Sandbox Code Playgroud)
( JLS 12 > 4.4. 类型变量 >TypeBound
)
如果我们要改变它,我们肯定会添加这个implements
案例
TypeBound:
extends TypeVariable
extends ClassType {AdditionalBound}
implements InterfaceType {AdditionalBound}
Run Code Online (Sandbox Code Playgroud)
并最终得到两个相同处理的子句
ClassOrInterfaceType:
ClassType
InterfaceType
Run Code Online (Sandbox Code Playgroud)
( JLS 12 > 4.3. 引用类型和值 >ClassOrInterfaceType
)
但我们还需要处理implements
,这会使事情变得更加复杂。
extends ClassOrInterfaceType
我相信这是使用 代替extends ClassType
and的主要原因implements InterfaceType
- 为了在复杂的概念中保持简单。问题是我们没有合适的词来涵盖这两者extends
,implements
而且我们绝对不想引入一个词。
<T is ClassTypeA>
<T is InterfaceTypeA>
虽然extends
它与接口一起使用时会带来一些混乱,但它是一个更广泛的术语,可以用来描述这两种情况。尝试将你的思想调整到扩展类型的概念(不是扩展类,不是实现接口)。您可以通过另一种类型来限制类型参数,并且该类型实际上是什么并不重要。唯一重要的是它是它的上限和它的超类型。
归档时间: |
|
查看次数: |
153797 次 |
最近记录: |