371 Stimmen

Warum ist "extends T" erlaubt, aber nicht "implements T"?

Gibt es in Java einen besonderen Grund für die Verwendung von immer " extends " statt " implements " für die Festlegung von Grenzen von Typparametern?

Zum Beispiel:

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

ist verboten, aber

public class A<B extends C>{} 

ist richtig. Was ist der Grund dafür?

7voto

Andrew Tobilko Punkte 45863

Wir sind es gewohnt

class ClassTypeA implements InterfaceTypeA {}
class ClassTypeB extends ClassTypeA {}

und jede kleine Abweichung von diesen Regeln verwirrt uns sehr.

Die Syntax einer Typbindung ist definiert als

TypeBound:
    extends TypeVariable 
    extends ClassOrInterfaceType {AdditionalBound}

( JLS 12 > 4.4. Typ-Variablen > TypeBound )

Wenn wir es ändern würden, würden wir sicherlich die implements Fall

TypeBound:
    extends TypeVariable 
    extends ClassType {AdditionalBound}
    implements InterfaceType {AdditionalBound}

und landen bei zwei identisch verarbeiteten Klauseln

ClassOrInterfaceType:
    ClassType 
    InterfaceType

( JLS 12 > 4.3. Referenztypen und -werte > ClassOrInterfaceType )

außer dass wir uns auch um Folgendes kümmern müssen implements was die Sache noch komplizierter machen würde.

Ich glaube, das ist der Hauptgrund, warum extends ClassOrInterfaceType verwendet wird, statt extends ClassType y implements InterfaceType - um die Dinge innerhalb des komplizierten Konzepts einfach zu halten. Das Problem ist, dass wir nicht das richtige Wort haben, um beides abzudecken extends y implements und wir wollen auf keinen Fall eine einführen.

<T is ClassTypeA>
<T is InterfaceTypeA>

Obwohl extends bringt ein gewisses Durcheinander mit sich, wenn es mit einer Schnittstelle einhergeht, es ist ein weiter gefasster Begriff und kann zur Beschreibung beider Fälle verwendet werden. Versuchen Sie, sich auf das Konzept der Erweiterung eines Typs (nicht eine Klasse erweitern , nicht Implementierung einer Schnittstelle ). Sie schränken einen Typ-Parameter durch eine andere Art und es spielt keine Rolle, um welchen Typ es sich handelt. Wichtig ist nur, dass es sein obere Schranke und es ist sein Supertyp .

5voto

Lii Punkte 10698

Es ist ziemlich willkürlich, welche der Begriffe man verwendet. Es könnte beides gewesen sein. Vielleicht dachten die Sprachdesigner an "extends" als den grundlegendsten Begriff und "implements" als den Spezialfall für Schnittstellen.

Aber ich denke implements würde etwas mehr Sinn machen. Ich denke, das kommuniziert eher, dass die Parametertypen nicht in einer Vererbungsbeziehung stehen müssen, sie können in cualquier Art der Subtyp-Beziehung.

Das Java-Glossar drückt eine ähnliche Ansicht .

0voto

zhangde Punkte 54

Bei der Verwendung von generic on interface ist das Schlüsselwort auch erweitert . Hier ist das Code-Beispiel:

Es gibt 2 Klassen, die die Schnittstelle Greeting implementieren:

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 ");
    }
}

Und der Testcode:

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

0voto

Die Verwendung von "extends" in <T extends Comparable> ist ein Versprechen, dass der Datentyp entweder selbst direkt Comparable implementiert oder aber eine Klasse erweitert, die Comparable implementiert. Sie könnten eine Unterklasse B einer anderen Klasse A geschrieben haben, die Comparable implementiert, und wenn Sie Ihren Datentyp als <T extends Comparable> deklarieren, können Sie bei der Instanziierung der Klasse entweder A oder B als Datentyp verwenden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X