Ich kenne diesen Code! :)
Lassen Sie uns also sicherstellen, dass Sie verstehen, was <:
bedeutet, nur für den Fall. A <: B
bedeutet, dass A
ein Subtyp von B
sein muss, oder, mit anderen Worten, jede Instanz von A
ist ebenfalls eine Instanz von B
(aber nicht umgekehrt).
Wir wissen zum Beispiel, dass jede Java-Klasse <: Object
ist (zB String <: Object
).
Als nächstes, warum type ValueChanged <: Event
. Dies wird normalerweise im Kuchenmuster gefunden, aber ich überspringe eine Erklärung davon (die Lektion erwähnt das Kuchenmuster und stellte einen Link dar).
Das bedeutet, dass für alles, was SwingApi
erweitert, der Typ ValueChanged
ein Untertyp von Event
sein muss. Das macht es möglich, Event
Methoden für alles aufzurufen, was mit dem Typ ValueChanged
deklariert wurde, ohne vorher genau zu wissen, um welchen Typ es sich handelt.
Das ist ähnlich wie bei der nächsten Verwendung:
%Vor% Wir erklären hier, dass TextField
diese Methoden haben sollte. Wenn wir also etwas vom Typ TextField
bekommen (wie es vom ValueChanged
Extraktor zurückgegeben wird), können wir diese Methoden aufrufen. Wir könnten Code wie folgt schreiben:
Zu diesem Zeitpunkt wissen weder SwingApi
noch MyStuff
, welche Typen für ValueChanged
oder TextField
verwendet werden, und sie können sie dennoch in normalem Code verwenden.
Eine interessante Tatsache, die bei type
-Deklarationen oft übersehen wird, ist, dass sie von Klassen überschrieben werden können. Das heißt, ich kann so etwas schreiben:
Schließlich fragen Sie sich vielleicht, was das für einen Nutzen ist. Ich werde ein Beispiel geben. Natürlich möchten Sie, dass der Produktionscode grafische Elemente auf dem Bildschirm anzeigt, und vielleicht könnten Sie eine separate Klasse schreiben, die sie auf einem Webserver implementiert. Aber, und ich denke natürlich, nutzt es, Sie könnten die Klasse schreiben, die es nicht als etwas implementiert, das diese Komponenten anzeigt, sondern als Testklassen , die sicherstellen, dass die Interaktion mit diesen Komponenten stattfindet richtig.
Das heißt, Sie können eine SwingImpl
haben, die SwingApi
erweitert und die Inhalte auf Ihrem Desktop anzeigt, und eine SwingTest
, die auch SwingApi
erweitert, aber lassen Sie die Leute einfach überprüfen, was gemacht wird.
Aufgrund des abstrakten Typs sind die Member ValueChanged
und ButtonClicked
, trait SwingApi
selbst unantastbar (alle Eigenschaften sind, aber wenn sie vollständig implementiert sind, werden sie trivialerweise in eine konkrete Klasse umgewandelt, die instanziiert werden kann).
Diese Einschränkungen sagen, dass instanziierbare Untertypen von SwingApi
ValueChanged
und ButtonClicked
als Untertypen von Event
definieren müssen.
Die Typ-Aliase TextField
und Button
sind als Strukturtypen eingeschränkt (sie benötigen keine bestimmte Unterklassenbeziehung, sondern müssen einfach die angegebenen Elemente mit den angegebenen Typen angeben).
Das warum davon ist einfach Allgemeingültigkeit. Dies setzt die minimalen Einschränkungen für die Implementierer von trait SwingApi
voraus, die für die Verwendung durch Code erforderlich sind, der ein SwingApi
verlangt.
Tags und Links scala type-constraints subtype