Ja, hi. Diese Woche geht es um Vererbung.
Dazu wird es auch wieder zwei Videos geben. In dem ersten
geht es um Typ-Vererbung und Polymorphie, anhand von einem kleinen Interface-Beispiel.
Und im zweiten Video wird es dann um Implementationsvererbung gehen.
Unser Interface-Beispiel, wir stellen uns vor, drei Leute haben
ein jeweils ein Sortierverfahren entwickelt und eine Klasse daraus gebaut.
Wir haben hier also quasi Fantastic Sword Megasword und Supersword.
Ihr merkt, die Leute sind echt sehr überzeugt von ihren Sortierverfahren.
Die Klassen tun jetzt nicht wirklich was. Da sind eigentlich eine Dummy-Implementation,
damit wir irgendwie was haben, womit wir spielen können.
Ich habe mir jetzt nicht irgendwelche neuen fancy Sortierverfahren ausgedacht.
Interessanter ist dann schon die Klasse, mit der wir die
Geschwindigkeiten vergleichen wollen. Die hat im Wesentlichen drei Methoden,
nämlich Time Tester Supersword, Time Tester Megasword und Time Tester
Fantastic Sword
Supersort nimmt ein Formalparameter vom Typ Supersort entgegen. Megasort,
das Gleiche mit Megasort und Fantastic Sort mit Fantastic Sort.
Wenn man sich die Methoden ein bisschen näher ansieht,
sieht man, dass die im Prinzip das Gleiche machen.
Es wird ein Startwert genommen. Es wird noch Nachname,
Vorname und Beruf sortiert. Es wird ein Stoppwert genommen,
voneinander abgezogen. Und das ist die verstrichene Zeit.
Warum brauchen wir dann also drei Methoden? Das liegt eben
daran, dass wir hier diese Variable vom statischen Typ der
jeweiligen Klasse haben
Und dann wäre es doch eigentlich cool,
wenn wir nur eine Testmethode bräuchten und hier so eine Art Oberbegriff,
Oberkategorie, Supertyp reintun könnten.
Ein Typ definiert ja eine Wertemenge und die Operationen,
die auf dieser Wertemenge möglich sind. Und das machen wir jetzt,
anhand von einem Interface und gucken mal,
ob wir damit dann den Code hier ein bisschen schöner machen können.
Wir machen also New Interface, nennen das Sortierer
Und das Interface soll genau die Operationen nach Nachname sortieren,
nach Vorname sortieren und nach Beruf sortieren haben.
Also kopiere ich mir das hier ganz frech einfach mal raus,
um mir hier ein bisschen Tipparbeit zu sparen.
Dann hier nach Nachname sortieren. Und nach Beruf sortieren Und
dann haben die drei Klassen auch noch jeweils eine Methode,
die uns einfach den Namen des Sortierers zurückgibt.
Das wollen wir für unser Interface auch haben.
Das kopieren wir hier raus. Tun uns auch ins Interface.
Und dann lassen wir die drei Klassen dieses Interface implementieren.
Wie ihr wisst, geht das mit Implements.
Und dann Sortierer. Das Gleiche mit Megasort
Und mit Supersort auch ganz nach oben. Ihr wisst ja noch,
wenn eine Klasse ein Interface implementiert, verspricht sie in Anführungsstrichen
für jede Operation aus diesem Interface auch eine Methode anzubieten.
Und das ist auch nötig,
damit wir hier das das Ganze dann auf eine Testklasse,
auf einen Time-Tester reduzieren können,
nehmen wir einfach mal den ersten und benennen den um den Time-Tester.
Der statische Typ, des formalen Parameters, wird sortierer.
Dann nennen wir die Variable auf Sortiere.
Kopieren uns die hier unten zu den Methoden aufrufen hin.
Und brauchen dann die beiden anderen Time Tester nicht mehr,
weil wir haben uns ja jetzt eingebaut,
in dem wir jede Art von Sortierer reintun können. Das funktioniert,
weil die drei Klassen hier das Interface Sortierer implementieren und damit versprochen haben,
dass sie eine Methode nach Nachname sortieren,
nach Vorname sortieren und nach Beruf sortieren haben,
sodass wir jedenfalls zur Laufzeit, wenn wir hier irgendwas reinstecken,
was vom statischen Typ Sortierer ist oder was das Interface Sortierer implementieren wir sicher sein können,
dass uns die Methode hier nicht auseinanderfliegt.
Wir können hier dann Die Methode, die eigentlichen Vergleiche aufruft,
auch noch ein bisschen schön am Nachchen,
das machen wir mit einer Four-Each-Schleife.
Da wird uns... Okay, das ist nicht so schön.
Ich hätte jetzt eigentlich gedacht, dass uns hier schon Sortierer angeboten worden wäre.
So, dann machen wir es von Hand.
Und das ist, ah, jetzt weiß ich auch,
warum das nicht passiert
Ich hatte was vergessen und zwar haben wir ja oben ja
noch die Exemplarvariablen. Die brauchen wir nicht mehr,
weil wir können uns jetzt einfach eine Liste bauen, vom Typ Sortierer.
Also mit Elementtyp Sortier, die nennen wir mal Sword.
Jetzt meckert er hier, weil er Liste nicht kennt,
also importieren wir diese Liste.
Dann müssen wir uns natürlich auf eine Liste erzeugen und sie
Sword zuweisen
Nehmen wir eine Arrailist. Element. Typ ist Sortierer.
Klammer auf, können wir zusehen wie Colan. Und da
wollen wir jetzt jeweils ein neues Exemplar der entsprechenden Sortierklassen hinzufügen,
zum Beispiel mal hier mit kopieren,
um mir wieder ein bisschen Tipparbeit zu sparen
Und mega Sword kommt da auch rein.
Und als letztes noch ein neues Exemplar der Klasse Fantastic Sword.
Diese drei brauchen wir nicht mehr,
zumal wir die Exemplarvariablen ja auch nicht mehr haben
Ah ja, Arrailist kennt er auch nicht.
Müssen wir auch importieren. Und jetzt können wir hier unten
unsere Sammlung schreiben, nämlich Sword. Das heißt,
für jeden Sortierer, den wir temporär Sortiere nennen,
aus der Sammlung Sword, tun wir Dinge.
Jetzt haben wir hier immer ganz viel System Out Printlines.
Wenn wir SYSO schreiben,
das ist auch der Shortcut der Woche und dann Steuerung leer machen,
schreibt er uns System Out Printline hin.
Dann können wir hier oben oder hier
rein gleich Sortierer schreiben,
lassen uns
den Namen geben
Verknüpfen dann mit einem Plus einen Doppelpunkt, so als Trennzeichen.
Und dann wiederum mit einem Plus Methodenaufruf von Time Tester.
Und da tun wir jetzt einen Sortierer rein.
Die jeweiligen Sortiere und die Daten kommen da hinten mit dran.
Diese drei Aufrufe brauchen wir auch nicht mehr.
Und wenn wir das Ganze jetzt speichern und Startup ist einfach
nur dafür da, Geschwindigkeitsvergleicher macht, irgendwo noch Probleme.
Ich habe wie immer einen Sinn mit Colan vergessen
Start-up ist eigentlich nur dazu dann eine Main-Methode zur Verfügung
zu stellen, um das Ganze ausführen zu können.
Wir lassen es jetzt laufen und wir sehen,
wir sehen noch nicht, aber gleich.
Und wir sehen, wir haben hier drei Messergebnisse gekriegt.
Was haben wir jetzt durch die ganze Aktion gewonnen?
Wir haben zum einen 20 Zeilen Code gespart. Wenn man bedenkt,
dass wir nur drei Sortierverfahren miteinander verglichen haben und hätten auch
20 oder 30 Sortierverfahren miteinander vergleichen können und hätten dann eben 19 oder 1929 Time-Test-Methoden gespart,
dann ist das schon einiges.
Was hat das Ganze mit Typvererbung zu tun? Die Klassen,
die das Interface Sortiere implementieren,
erben im Prinzip diesen super Typ und es kann an jeder Stelle,
an der eine Referenzvariable vom statischen Typ des Interfaces steht,
dynamisch ein Objekt einer jeden Klasse,
die dieses Interface implementiert, zugewiesen werden.
Das ist auch diese Polymorphie-Fielgestaltigkeit. Die Referenz variable Sortierer
nimmt zur Laufzeit als dynamischen Typ mal Fantastic Sword,
mal Megasword und mal Supersword an.
Das heißt also, halb zur Laufzeit unterschiedliche Gestalten.
Das war's jetzt zur Typvererbung und zur Polymorphie und im nächsten Video
geht es dann um die Implementationsvererbung,
um das Redefinieren von Methoden und um den Zusammenhang mit dem
Vertragsmodell und der Vererbung