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?

351voto

Tetsujin no Oni Punkte 7222

In der generischen Constraint-Sprache gibt es keinen semantischen Unterschied, ob eine Klasse "implementiert" oder "erweitert". Die Constraint-Möglichkeiten sind "extends" und "super" - das heißt, ist diese Klasse, mit der operiert werden soll, der anderen zuordenbar (extends), oder ist diese Klasse von der anderen zuordenbar (super).

118voto

MikaelF Punkte 3286

Die Antwort liegt in aquí  :

Um einen begrenzten Typparameter zu deklarieren, führen Sie den Namen des Typparameters auf, gefolgt von der extends Schlüsselwort, gefolgt von seinem obere Schranke [ ] . Beachten Sie, dass in diesem Zusammenhang "erweitert" in einem allgemeinen Sinn verwendet wird, um entweder extends (wie in Klassen) oder implements (wie bei den Schnittstellen).

Sie sehen also, es ist etwas verwirrend, und Oracle weiß das.

20voto

beetstra Punkte 7806

Wahrscheinlich, weil für beide Seiten (B und C) nur der Typ relevant ist, nicht die Implementierung. In Ihrem Beispiel

public class A<B extends C>{}

B kann auch eine Schnittstelle sein. "extends" wird verwendet, um Unterschnittstellen und Unterklassen zu definieren.

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

Normalerweise denke ich bei 'Sub extends Super' an ' Unter ist wie Super , aber mit zusätzlichen Fähigkeiten', und 'Clz implementiert Intf' als ' Clz ist eine Realisierung von Intf '. In Ihrem Beispiel würde dies passen: B ist wie C , jedoch mit zusätzlichen Funktionen. Die Fähigkeiten sind hier relevant, nicht die Umsetzung.

8voto

ntg Punkte 10508

Hier ein ausführlicheres Beispiel dafür, wo Erweiterungen zulässig sind und was Sie möglicherweise wünschen:

public class A<T1 extends Comparable<T1>>

7voto

Tom Hawtin - tackline Punkte 142461

Es kann sein, dass der Basistyp ein generischer Parameter ist, so dass der eigentliche Typ eine Schnittstelle einer Klasse sein kann. Überlegen Sie:

class MyGen<T, U extends T> {

Auch aus der Sicht des Client-Codes sind Schnittstellen kaum von Klassen zu unterscheiden, während sie für den Untertyp wichtig sind.

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