Ich weiß, das ist keine gute Frage, die ich stellen kann, und ich werde vielleicht verflucht, um sie zu fragen, aber ich kann keinen Platz finden, um Hilfe zu dieser Frage zu bekommen.
Unten ist eine generische Klasse, die in meiner Interviewfrage (die ich bereits gescheitert bin) erschienen ist. Die Frage war zu sagen, was diese Klasse Erklärung tut und unter welchen Umständen könnte dies verwendet werden?
Ich habe sehr wenig Verständnis für generische Programmierung, aber ich verstehe, dass "T" Typ ist und "erweitert" bedeutet hier, dass der Typ "SimpleGenericClass" geerbt haben sollte, aber ich verstehe nicht das "?" Am Ende und unter welchen Umständen könnte diese Klasse möglicherweise für
verwendet werden %Vor% Erstens, weil die Klasse SimpleGenericClass
abstrakt ist, soll sie unterklassifiziert sein.
Zweitens ist es eine generische Klasse, was bedeutet, dass Sie innerhalb der Klasse fast sicher den generischen Parameter T
als Typ eines Feldes verwenden.
Das erste ist hier interessant, dass T
begrenzt ist. Weil es als T extends SimpleGenericClass<?>
deklariert ist, kann es nur SimpleGenericClass<?>
oder eine Unterklasse von SimpleGenericClass<?>
sein. Sie haben auch nach thr ?
gefragt. Das ist bekannt als Wildcard und es gibt eine ziemlich gute Erklärung dafür im Java-Tutorial zu Wildcards . In Ihrem Fall würden wir sagen, dass dies eine "SimpleGenericClass of unknown" ist. Es wird in Java benötigt, weil SimpleGenericClass<Object>
beispielsweise NICHT die Oberklasse von SimpleGenericClass<String>
ist.
Die zweite interessante Sache ist jedoch, dass Ihre Klasse mehr als wahrscheinlich rekursive Strukturen definiert, da T
ein SimpleGenericClass
irgendeiner Art ist. Was mir in den Sinn kommt, sind Bäume (denke an Ausdrucksbäume), wobei SimpleGenericClass
der (abstrakte) Knotentyp ist, der entworfen wurde, um mit allen Arten von spezialisierten Knotentypen unterklassifiziert zu werden.
UPDATE Diese SO-Frage zu selbstbegrenzten Generika könnte für Sie hilfreich sein.
UPDATE 2
Ich habe einen Code erstellt, der veranschaulicht, wie man das verwenden kann. Die App tut nichts, aber sie kompiliert und zeigt Ihnen, wie die generischen Grenzen einige möglicherweise sinnvolle Einschränkungen liefern können.
%Vor% Das Schöne ist, dass NumberNode[]
ein gültiger Rückgabetyp für PlusNode.getChildren
ist! Spielt das in der Praxis eine Rolle? Keine Ahnung, aber es ist ziemlich cool. :)
Es ist nicht das beste Beispiel, aber die Frage war ziemlich offen ("Wofür könnte so etwas verwendet werden?"). Es gibt natürlich andere Möglichkeiten, Bäume zu definieren.
Dies bedeutet eigentlich nur, dass Sie dem Benutzer der Klasse SimpleGenericClass die Möglichkeit geben, Instanzen der Klasse mit dem Typ T zu parametrisieren. T kann jedoch kein Typ sein, sondern muss ein Subtyp von SampleGenericClass (oder SampleGenericClass selbst) sein >
Im Rest des Codes der Klasse SimpleGenericClass können Sie Typ T in Methodensignaturen verwenden.
Lassen Sie uns für eine Sekunde annehmen, dass SimpleGenericClass nicht abstrakt ist. Wenn Sie es verwenden, könnten Sie dann schreiben:
%Vor%i.e. Sie parametrisieren SimpleGenericClass mit SampleGenericClass und SampleGenericClass mit String.
Dies ist im Grunde genommen so: In dieser Klasse haben Sie einen Typ-Platzhalter namens T und eine Einschränkung für diesen Platzhalter, er muss vom Typ SimpleGenericClass sein oder etwas, das ihn erweitert. Sobald Sie diese Regel befolgt haben, können Sie Instanzen Ihrer Klasse erstellen und T einen tatsächlichen Typ geben, der später in Methoden dieser Klasse verwendet werden kann, etwa so:
%Vor% Die SimpleGenericClass<?>
ist zu diesem Zeitpunkt ziemlich überflüssig. Wenn für diese Klasse ein anderer generischer Typ benötigt wird, können Sie mehr als einen ( SimpleGenericClass<T extends SimpleGenericClass, T2 extends Whatever>
)
Per Definition heißt es, dass SimpleGenericClass
mit einem Typ <T>
arbeiten kann, der eine Unterklasse von SimpleGenericClass ist.
Ich nehme also an, dass es einige Operationen geben wird, die auf <T>
funktionieren.
Nun, um zu sehen, warum man ein Template wie dieses definieren würde - (nicht viel, was ich mir wirklich vorstellen kann), könnte ein Szenario sein, in dem SimpleGenericClass
eine abstrakte Klasse ist ( hat gerade gemerkt: P ) und erwartet, dass es an konkreten Klassen arbeiten kann?
Jungs, was denkst du?
Ich nehme an, Sie haben die Frage in dieser Form ( T
anstelle von ?
):
Sehen Sie sich diesen Code an:
%Vor% Der Trick mit Foo<SubClassOfFoo extends Foo<SubClassOfFoo>>
ist:
Foo
muss ein Typargument an Foo
liefern. Foo
sein. Unterklassen von Foo
(wie Bar
) folgen dem Idiom des Typs
Argument, das sie an Foo
liefern, ist sie selbst.
Foo hat eine Methode, die SubClassOfFoo
zurückgibt. Kombiniert
mit dem obigen Idiom erlaubt dies Foo, einen Vertrag zu formulieren, der
sagt "irgendeine Unterklasse von mir muss subclassAwareDeepCopy()
und implementieren
Sie müssen deklarieren, dass sie die tatsächliche Unterklasse ".
Anders gesagt: Dieses Idiom ermöglicht einer Oberklasse (wie etwa einer abstrakten Fabrik), Methoden zu definieren, deren Argumenttypen und Rückgabetypen vom Unterklasse-Typ und nicht vom Oberklasse-Typ abhängen.
Der Trick ist zum Beispiel in Enum
JDK Klasse:
Weitere Informationen finden Sie hier .
Tags und Links java generics generic-programming