在Java中总是使用“extends”而不是“implements”来定义类型参数的边界是否有特殊的原因?

例如:

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

是禁止的,但是

public class A<B extends C>{} 

是正确的。原因是什么?


当前回答

使用哪个术语有点随意。两种情况都有可能。也许语言设计者认为“扩展”是最基本的术语,而“实现”是接口的特殊情况。

但我认为工具会更有意义一点。我认为这更多地说明了参数类型不必处于继承关系中,它们可以处于任何类型的子类型关系中。

Java Glossary表达了类似的观点。

其他回答

在泛型约束语言中,类是“实现”还是“扩展”在语义上没有区别。约束的可能性是“extends”和“super”——也就是说,这个类是否可以赋值给另一个类(extends),或者这个类是否可以从那个类(super)赋值。

实际上,在接口上使用generic时,关键字也是extends。下面是代码示例:

有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();
}

使用哪个术语有点随意。两种情况都有可能。也许语言设计者认为“扩展”是最基本的术语,而“实现”是接口的特殊情况。

但我认为工具会更有意义一点。我认为这更多地说明了参数类型不必处于继承关系中,它们可以处于任何类型的子类型关系中。

Java Glossary表达了类似的观点。

在<T extends Comparable>中使用" extends "是保证数据类型本身直接实现Comparable,或者扩展实现Comparable的类。您可能已经编写了实现Comparable的另一个类a的子类B,如果您声明您的数据类型<T extends Comparable>,那么在实例化该类时可以使用a或B作为您的数据类型。

答案就在这里:

要声明一个有界类型参数,列出类型参数的名称,后跟extends关键字,再后跟它的上界[…]。注意,在此上下文中,extends在一般意义上用于表示扩展(如类)或实现(如接口)。

所以你知道了,这有点令人困惑,甲骨文知道这一点。