Java泛型 - 为什么允许“扩展T”而不是“实现T”?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java泛型 - 为什么允许“扩展T”而不是“实现T”?相关的知识,希望对你有一定的参考价值。

我想知道Java中是否有特殊原因使用始终使用“extends”而不是“implements”来定义类型参数的边界。

例:

public interface C {}
public class A<B implements C>{} 

被禁止但是

public class A<B extends C>{} 

是正确的。这是什么原因?

答案

在类'实现'或'扩展'之间的通用约束语言中没有语义差异。约束的可能性是“扩展”和“超级” - 也就是说,这个类是否可以分配给另一个(扩展),或者这个类可以从那个(超级)分配。

另一答案

答案是在here

要声明有界类型参数,请列出类型参数的名称,然后是extends关键字,后跟其上限[...]。请注意,在此上下文中,extends在一般意义上用于表示extends(如类中)或implements(如接口中)。

所以,你有它,它有点令人困惑,Oracle知道它。

另一答案

可能是因为对于双方(B和C),只有类型是相关的,而不是实现。在你的例子中

public class A<B extends C>{}

B也可以是界面。 “extends”用于定义子接口和子类。

interface IntfSub extends IntfSuper {}
class ClzSub extends ClzSuper {}

我通常认为'Sub extends Super'是'Sub就像Super,但有额外的功能','Clz实现Intf'为'Clz是Intf的实现'。在您的示例中,这将匹配:B类似于C,但具有其他功能。这些功能与此相关,而不是实现。

另一答案

可能是基类型是通用参数,因此实际类型可以是类的接口。考虑:

class MyGen<T, U extends T> {

此外,从客户端代码角度来看,接口几乎与类无法区分,而对于子类型,它很重要。

另一答案

这是一个更为复杂的例子,其中允许扩展,也可能是你想要的:

public class A<T1 extends Comparable<T1>>

另一答案

这是任意使用哪个术语。它可能是两种方式。也许语言设计者认为“扩展”是最基本的术语,并且“实现”作为接口的特殊情况。

但我认为implements会更有意义。我认为更多地传达参数类型不必处于继承关系中,它们可以处于任何类型的子类型关系中。

Java Glossary表达了similar view

另一答案

在这种情况下,“扩展”意味着就像接口中的实现一样,并在类中扩展。 Here is more explanation

另一答案

因为接口只是类,除了它们没有属性或实现。关键字“implements”的唯一用法是允许类继承多个接口,但不能继承多个类,我们可以在代码中看到它。我不知道他们将来是否会指定这个,但这不是必须的。

以上是关于Java泛型 - 为什么允许“扩展T”而不是“实现T”?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 C# 允许将泛型数组与所有类型的模式进行匹配?

java泛型

第六节:Java泛型

为啥 Java 泛型不允许对泛型类型进行类型转换?

为啥 Java 不允许 Throwable 的泛型子类?

找出一个类型是不是实现了一个泛型接口