我想知道Java中是否有特殊原因使用“extends
”而不是“implements
”来定义类型参数的边界。
示例:
public interface C {}
public class A<B implements C>{}
被禁止但
public class A<B extends C>{}
是对的。这是什么原因?
答案 0 :(得分:320)
在类“实现”或“扩展”之间,通用约束语言没有语义差异。约束的可能性是'extends'和'super' - 也就是说,这个类是否可以赋值给另一个(扩展),或者这个类可以从那个(超级)分配。
答案 1 :(得分:56)
答案在here:
要声明有界类型参数,请列出类型参数的名称,然后是
extends
关键字,后跟上限 [...]。请注意,在此上下文中,extends在一般意义上用于表示extends
(如在类中)或implements
(如在接口中)。
所以,你有它,它有点令人困惑,而甲骨文知道它。
答案 2 :(得分:17)
可能因为双方(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 ,但具有其他功能。这些功能与此相关,而不是实现。
答案 3 :(得分:7)
基类型可能是通用参数,因此实际类型可能是类的接口。考虑:
class MyGen<T, U extends T> {
同样从客户端代码的角度来看,接口几乎与类无法区分,而对于子类型则很重要。
答案 4 :(得分:7)
这是一个更为复杂的例子,其中允许扩展,也可能是你想要的:
public class A<T1 extends Comparable<T1>>
答案 5 :(得分:5)
使用哪种术语是任意的。它可能是两种方式。也许语言设计师认为&#34;扩展&#34;作为最基本的术语,&#34;实现&#34;作为接口的特例。
但我认为implements
会更有意义。我认为更多地传达参数类型不必处于继承关系中,它们可以处于任何类型的子类型关系中。
Java词汇表表达similar view。
答案 6 :(得分:1)
我们习惯
class ClassTypeA implements InterfaceTypeA {}
class ClassTypeB extends ClassTypeA {}
与这些规则的任何微小差异都会使我们感到困惑。
类型绑定的语法定义为
TypeBound:
extends TypeVariable
extends ClassOrInterfaceType {AdditionalBound}
(JLS 12 > 4.4. Type Variables > TypeBound
)
如果要更改它,我们肯定会添加implements
大小写
TypeBound:
extends TypeVariable
extends ClassType {AdditionalBound}
implements InterfaceType {AdditionalBound}
并以两个相同处理的子句结束
ClassOrInterfaceType:
ClassType
InterfaceType
(JLS 12 > 4.3. Reference Types and Values > ClassOrInterfaceType
)
除了我们还需要注意implements
,这会使事情进一步复杂化。
我认为,这是使用extends ClassOrInterfaceType
而不是extends ClassType
和implements InterfaceType
的主要原因-在复杂的概念中使事情保持简单。问题在于我们没有一个合适的词来涵盖extends
和implements
,而且我们绝对不想引入一个词。
<T is ClassTypeA>
<T is InterfaceTypeA>
尽管extends
在与接口一起使用时会带来一些混乱,但这是一个广义的术语,可以用来描述这两种情况。尝试使您的思想适应扩展类型的概念(而不是扩展类,而不是实现接口)。您可以通过另一种类型来限制类型参数,实际上该类型是什么都没有关系。唯一重要的是它的上限和它的超类型。
答案 7 :(得分:-1)
实际上,当在接口上使用泛型时,关键字也会扩展。这是代码示例:
有2个类实现了Greeting接口:
interface Greeting {
void sayHello();
}
class Dog implements Greeting {
@Override
public void sayHello() {
System.out.println("Greeting from Dog: Hello ");
}
}
class Cat implements Greeting {
@Override
public void sayHello() {
System.out.println("Greeting from Cat: Hello ");
}
}
测试代码:
@Test
public void testGeneric() {
Collection<? extends Greeting> animals;
List<Dog> dogs = Arrays.asList(new Dog(), new Dog(), new Dog());
List<Cat> cats = Arrays.asList(new Cat(), new Cat(), new Cat());
animals = dogs;
for(Greeting g: animals) g.sayHello();
animals = cats;
for(Greeting g: animals) g.sayHello();
}