Am 14. September 2017 haben wir eine überarbeitete Fassung unserer Datenschutzrichtlinie veröffentlicht. Wenn Sie video2brain.com weiterhin nutzen, erklären Sie sich mit diesem überarbeiteten Dokument einverstanden. Bitte lesen Sie es deshalb sorgfältig durch.

Java 7 Grundkurs

Polymorphie

LinkedIn Learning kostenlos und unverbindlich testen!

Jetzt testen Alle Abonnements anzeigen
Polymorphie beschreibt die Fähigkeit eines Bezeichners, abhängig von seiner Verwendung unterschiedliche Datentypen anzunehmen. Sehen Sie im Video dazu mehr.
10:05

Transkript

In diesem Video zeige ich Ihnen, was Polymorphie ist und was Typumwandlungen damit zu tun haben. Ich verwende dafür dieses kleine Beispiel, in dem ich eine Klasse "Auto" habe und eine Unterklasse "Cabrio". Im Augenblick erzeuge ich hier ein Auto, auf das ich mit einer Variablen vom Typ "Auto" verweise. Dann deklariere ich mir eine neue Variable vom Typ "Cabrio", also der Unterklasse von "Auto", und mache hier eine Typumwandlung, so dass die Zuweisung am Compiler vorbeigeht. Durch diesen "Type Cast", diese Typumwandlung, vor dem "A" sage ich dem Compiler, dass ich weiß, was ich tue, und dass ich glaube, dass dieses "A" auf ein Cabrio verweist. Dann sagt der Compiler: "OK, dann mach mal!" und ich darf in der nächsten Zeile eine Cabrio-typische Methode aufrufen. Ich habe den Compiler hier ausgetrickst, und wenn ich zur Laufzeit versuche, das Ganze auszuführen, ich klicke mit der rechten Maustaste rein und sag "Run File", dann bekomme ich hier eine "Class Cast Exception", denn das Auto wehrt sich, wenn ich versuche, es als Cabrio zu betrachten. Damit das Ganze funktioniert, muss ich also dafür sorgen, dass das wirklich ein Cabrio ist, was ich hier ansprechen möchte. Ich ändere also hier oben den Namen des Konstruktors auf "Cabrio". Dann ist alles wieder gut. Rechte Maustaste, "Run File", und ich bekomme "Dach wird geöffnet". Wozu nun aber dieses ganze Hin und Her? Cabrio-Auto, Auto-Cabrio, warum nicht immer auf der linken und auf der rechten Seite denselben Typ verwenden, so dass alles immer zusammenpasst? Um diese Frage zu beantworten, füge ich einmal einen neuen Akteur in unsere kleine Autowelt ein, und zwar einen Mechaniker. Dabei möchte ich unsere kleine Paketstruktur hier konsistent halten. Bisher haben wir ein Paket "com.video2brain.Java7.autos" und darin ein Unterpaket "fahrzeuge", in dem sich "Auto" und "Cabrio" befinden. Der Mechaniker kommt jetzt in ein parallel dazu angelegtes Paket "Nutzer". Ich lege Paket und Klasse gleichzeitig an und das mache ich folgendermaßen: Ich klicke hier auf das Paket "Autos" mit der rechten Maustaste und sage "New Java Class", dann gebe ich hier oben als Klassennamen ein "Mechaniker", und hier bei "Package" steht jetzt "Autos", und da schreibe ich dahinter ".nutzer", fertig! Wir sehen, es gibt jetzt das Paket "Autos", das Paket "Fahrzeuge" innerhalb von "Autos" und das Paket "Nutzer" innerhalb von "Autos" und in diesem Nutzerpaket ist unser Mechaniker. Den Kommentar hier oben nehme ich einmal weg. So, was macht ein Mechaniker? Ein Mechaniker repariert Autos, das heißt, der Mechaniker bekommt eine Methode, die muss nichts zurückgeben, und die Methode heißt "Reparieren". Diese Methode nimmt ein Auto. "Auto" befindet sich in einem anderen Paket. Wir müssen also hier importieren. Dann ist der Compiler wieder glücklich. Wir wollen es nicht unnötig kompliziert machen, wir geben hier einfach eine kurze Statusmeldung aus. Das Kürzel "sout" in Verbindung mit der Tabulator-Taste bringt uns zu "System.out.println", da schreiben wir jetzt hinein "Ich repariere" und dazu den Namen des Autos, wir sehen hier "getName" wird sogar vorgeschlagen. Also einfach nur Enter drücken zum Übernehmen. Jetzt wollen wir diesen Mechaniker einmal ausprobieren. Dazu gehen wir wieder in unsere Hauptklasse "Typen", und das hier nehmen wir einmal weg; wir erstellen ein Auto-Objekt. Dazu brauchen wir eine passende Variable "Auto", nennen wir sie einfach "Auto", und dieses Auto nennen wir "Anton", und dann bauen wir uns noch einen Cabrio. Die Variable nenne ich einfach "Cabrio", und das Cabrio bekommt den Namen "Carla". Also diesmal kein Hin und Her. Auto-Objekt, Referenzvariable vom Typ "Auto", Cabrio-Objekt, Referenzvariable vom Typ "Cabrio". Jetzt bauen wir uns einen Mechaniker. Auch den Variablen-Namen kann man sich von der IDE mit Strg-Leertaste geben lassen. Also "new Mechaniker()", und jetzt rufen wir die Reparieren-Methode auf. "mechaniker.reparieren(auto)". Das funktioniert? Klar, funktioniert das. Dem Mechaniker haben wir ja hier das Ganze auch vom Typ "Auto" deklariert, und hier übergeben wir auch ein Auto. Jetzt können wir aber auch zum Mechaniker gehen und "reparieren" aufrufen und das Cabrio übergeben. Offensichtlich gibt es keinen Compilerfehler. Der Mechaniker braucht also nicht für jedes spezielle Auto eine eigene Methode, die wir dann aufrufen können, sondern alle Autos können wir an diese Methode übergeben. Alles, was Unterklasse von "Auto" ist, ist ja auch ein Auto, es ist also auch vom Typ "Auto". Ich kann es also an diese Methode übergeben. Nur verwende ich also doch verschiedene Typen, und zwar im Mechaniker, den Typ "Auto", und hier beim Aufruf, den Typ "Cabrio". Ich führe das einmal aus, dass wir einmal sehen, dass das auch funktioniert. Rechte Maustaste, "Run File", und dann sehen wir: "Ich repariere Anton" und "Ich repariere Carla". Das Ganze geht sogar noch weiter. Gehen wir noch einmal in den Mechaniker hinein und erweitern diese Reparieren-Methode um eine Zeile, und zwar, gebe ich jetzt hier noch die Statusmeldung des jeweiligen Autos aus. Also noch einmal "sout" und dann hier einfach "auto". Dieses Auto ist das Auto, was übergeben wird. Und wenn ich ein Objekt an die Methode "println" übergebe, dann geht "println" zu diesem Objekt hin und ruft von dem die "toString"-Methode auf, und wenn wir jetzt gleich in die beiden Klassen "Auto" und "Cabrio" hineinschauen, dann werden wir feststellen, dass die beide verschiedene "toString"-Implementierungen haben. In der Klasse "Auto" sehen wir hier "toString", steht drin "Name fährt gerade Geschwindigkeit km/h", und in "Cabrio" ist die "toString"-Methode so implementiert: Es wird zuerst zur Oberklasse gegangen, also "Auto"; das was dort von "toString" zurückgegeben wird, wird verwendet, und hinten dran kommt noch "und das Dach ist gerade "offen" oder "geschlossen". Der Mechaniker weiß aber nichts davon, ob das jetzt ein Cabrio ist oder ob es nur ein Auto ist. Es könnte auch ein Traktor oder ein Lkw sein. Für den Mechaniker sind das alles einfach nur "Autos". Er geht also zu dem "Auto" hin und lässt "toString" vom "Auto" aufrufen. Wenn wir das jetzt ausführen, dann klappt das natürlich nicht, denn wir können den Mechaniker ja nicht ausführen. Wir müssen zu unserer Hauptklasse gehen. "Ausführen" und dann sehen wir "Ich repariere Anton", "Anton fährt gerade 0 km/h"; das ist also offensichtlich die "toString"-Methode aus "Auto" und jetzt kommt "Ich repariere Carla", "Carla fährt gerade 0 km/h" und "Das Dach ist gerade geschlossen", Das heißt, hier haben wir die "toString"-Methode aus "Cabrio". Der Mechaniker behandelt also verschiedene Objekte auf die gleiche Weise, und diese verschiedenen Objekte verhalten sich dann verschieden entsprechend ihrem speziellen Typ. Und für dieses Konzept "Gleiche Schnittstelle, unterschiedliches Verhalten dahinter" gibt es einen Begriff, und der heißt "Polymorphie", das heißt wörtlich "Vielgestaltigkeit". Die Schnittstelle ist in "Auto" festgelegt, nämlich die Methoden, die ich aufrufen kann, und das Verhalten ist dann in den jeweiligen Unterklassen festgelegt. Das Objekt, das ich hier an "Reparieren" übergebe, weiß selbst sehr genau, was für ein Objekt es ist, und es verhält sich dann auch entsprechend. Aus Sicht des Mechanikers hat das Ganze noch einen Schönheitsfehler. Er kann, da hier ja nur der Typ "Auto" verwendet wird, auch nur die Methoden benutzen, die in "Auto" bereits festgelegt sind. Bauen wir also zum Abschluss noch eine kleine Erweiterung ein. Der Mechaniker schaut nach, ob es ein Cabrio ist, und, wenn es ein Cabrio ist, dann öffnet und schließt er das Dach einmal. Das funktioniert folgendermaßen: Er muss zuerst nachschauen, ob dieses Auto ein Cabrio ist. Dafür gibt es einen speziellen Operator, und zwar, heißt der "instanceof". Ich schreibe also "if (auto instanceof Cabrio", jetzt muss ich wieder importieren. Klick, klick, Enter. Jetzt wissen wir zwar schon, dass das Objekt ein Cabrio-Objekt ist, aber wir haben dem Compiler noch nicht die richtige Brille aufgesetzt. Das müssen wir noch tun, das heißt, also hier brauchen wir eine kleine Typumwandlung. Die sieht so aus. Wohlgemerkt, das Objekt bleibt das, was es ist. Wir ändern nur den Typen der Referenzvariablen, mit der wir auf das Objekt zugreifen. Jetzt ist die Variable vom Typ "Cabrio", wir können also tatsächlich das Dach einmal öffnen und das Dach einmal schließen. Ein letzter Testlauf, diesmal in der Hauptklasse. Rechte Maustaste, "Run File", und wir sehen: "Ich repariere Anton", "Anton fährt 0 km/h" — keine Rede von irgendeinem Dach, jetzt kommt "Ich repariere Carla", "Carla fährt 0 km/h", "Das Dach ist geschlossen", "Dach wird geöffnet", "Dach wird geschlossen". Über den "instanceof"-Operator können wir also herausfinden, ob ein Objekt von einem ganz bestimmten Typ ist. Er funktioniert immer auf dieselbe Weise: Auf der rechten Seite schreibe ich irgendeinen Typ hin, auf der linken Seite irgendeine Referenzvariable. Als Ergebnis bekomme ich "true", wenn die Variable auf ein Objekt von diesem Typ zeigt und "false", wenn nicht. Setzen Sie dieses "instanceof" möglichst sparsam ein. Wenn Sie sehr viel Cabrio-spezifische Funktionalität benötigen würden, dann sollten Sie vielleicht lieber einen spezialisierten Mechaniker bauen, der sich mit Cabrios auskennt und der auch nur Cabrios als Parameter akzeptiert.

Java 7 Grundkurs

Machen Sie sich mit den Grundlagen der Java-Programmierung vertraut und lernen Sie die Syntax der Sprache sowie das Konzept der objektorientierten Softwareentwicklung kennen.

8 Std. 32 min (66 Videos)
Derzeit sind keine Feedbacks vorhanden...
 

Dieser Online-Kurs ist als Download und als Streaming-Video verfügbar. Die gute Nachricht: Sie müssen sich nicht entscheiden - sobald Sie das Training erwerben, erhalten Sie Zugang zu beiden Optionen!

Der Download ermöglicht Ihnen die Offline-Nutzung des Trainings und bietet die Vorteile einer benutzerfreundlichen Abspielumgebung. Wenn Sie an verschiedenen Computern arbeiten, oder nicht den ganzen Kurs auf einmal herunterladen möchten, loggen Sie sich auf dieser Seite ein, um alle Videos des Trainings als Streaming-Video anzusehen.

Wir hoffen, dass Sie viel Freude und Erfolg mit diesem Video-Training haben werden. Falls Sie irgendwelche Fragen haben, zögern Sie nicht uns zu kontaktieren!