So, im dritten Abschnitt geht es um Vererbungskonzepte. Das ist das,
was wir hier mit dem Überschrift Typ Hierarchien und Vererbungskonzepte besprochen haben.
Wir möchten dabei insbesondere noch ein Beispiel bringen, was gut
und schlecht ist. Das werden also auch die Frage 4,
die wir vorhin aufgeschoben haben, hier nochmal besprechen.
Beginnen tue ich dieser Abschnitt ab, Folie mit der Nummer 19.
Hier fangen wir mal an mit einem Klassendiagramm. Sie kennen
diese Symbolik hoffentlich noch oder schon das Klassendiagramm der UML.
Die Klassen sind diese Kästen und das,
was wir als diese Pfeile mit ausgezogenen Linien und weißen Dreieck haben,
das sind die Pfeile für die Abstraktions- beziehungsweise Generalisierungs- und Spezialisierungsbeziehungen,
die wir hier für Vererbung gerne einsetzen.
Im oberen Teil sehen wir Typ Hierarchien, das ist das,
was wir bei SE1 schon mit Ihnen besprochen haben.
Hier zum Beispiel die klasse Collection, nein,
Verzeihung nicht klasse, das Interface natürlich,
das Interface Collection und dieses Interface hat zum Beispiel definiert eine Operation at.
Und hier haben wir eine Verfeinerung davon,
nämlich das Interface Set und hier das Interface List.
Nun könnte man gleich fragen, was ist denn der Unterschied,
was ist das Spezielle, ein Set und List.
Sie wissen alle hoffentlich noch, Collection ist zum Sammeln,
zum Zusammenfassen von mehreren Elementen. Das ist ein mächtiges Konzept in Java,
kommt mit den Klassenbibliotheken und das werde ich Sie aber fragen in unserer Fragerunde.
Da können Sie sich gerne schon mal darauf vorbereiten und mal nachschauen,
was war nochmal das Spezielle bei Set und was war das Spezielle bei List.
Auf jeden Fall haben Set und List diese beiden Interfaces definieren, ebenfalls eine Operation at.
Und wir können ja annehmen, wenn die was unterschiedliches machen,
dass da auch die Operation at ein bisschen unterschiedlich ist.
Hier haben wir so einen ganz ähnlichen Pfeil und das
steht für die Typ-Abstraktion, die Implements-Beziehung. In Java,
tatsächlich ist das das Schlüsselwort, Implements, die Klasse Abstraktlist,
implementiert das Interface-List, in dem wir hier für dieses Et,
was wir hier nur als Operation haben,
nur als Definition,
eine Operation,
haben wir hier tatsächlich dann
auch einen Quelltext
Hier und haben wir die gleiche Symbolik nochmal,
die wir hier oben schon für Interfaces hatten,
haben wir hier unten für Klassen.
Und zwar die Klasse Linklist ist ein Subklasse,
eine Unterklasse von der Klasse Abstraktlist und genauso eure Elist.
Und hier haben wir tatsächlich eine Implementationsvererbung. Und das wäre damit
gleichzeitig Wiederverwendung. Die nächste Folie zeigt, dass nochmal in
der Bezeichnung darüber und hier nochmal die UML-Symbole etwas größer.
Ja, also das, was wir unten hatten,
waren die Klassen, die sind in Java über eine Extensbeziehung Verknüpft,
ich spring mal eine Folie zurück.
Ja, das war das hier unten. Wir haben die
Extenz-Beziehung und die wird dargestellt im UML-Klassendiagramm durch das weiße Dreieck mit einem durchgezogenen Pfeil.
Und dabei haben wir tatsächlich Code-Wiederverwendung, nämlich Implementationsvererbung.
Das Gleiche haben wir nochmal, was in dem Bild ganz
oben war zwischen Interfaces, auch die Extenz-Beziehung und des Extenz-Schlüsselwort
Extenz ist tatsächlich hier mehrfach benutzt, zweifach benutzt in dem Fall, überladen.
Und wir haben es hier der gleiche Pfeil in UML
Das haben wir, ich gehe mal zurück, eine Folie.
Ja, also hier oben, hier unten hatten wir
das Gleiche. Nochmal, wie wir oben. So,
und dann gibt es noch dazwischen, was hier in der Mitte stehe,
ich stand auf dem anderen auch in der Mitte,
die Beziehung zwischen Klasse und Interface,
in Java ist das die Implementsbeziehung.
Ja, und das steht für die Typ-Abstraktion.
Dafür haben wir im Klassendiagramm der OML einen gestrichelten Pfeil mit
diesem weiß gefüllten Dreieck.
Soweit,
soweit dazu
Diese Typ-Abstraktion kennen Sie schon, ja, dort haben wir
den abstrakten Datentyp, dem wir dann irgendwie implementieren.
Hier ist ja eben dieses Beispiel wieder List, ja,
und wir brauchen dafür eine Implementation. Wenn wir,
da werdet ihr oben nur die Definition der Operation haben und
hier unten diese Definition einfach ausgefüllt wird, sollten wir,
jedenfalls im Idealfall,
die Implementation auch austauschen können
Sie braucht keine zusätzlichen Operationen weiter zu definieren, außer der Sachen,
außer denen, die wir in der Definition brauchen,
aber es wird vermutlich Unterschiede geben, in irgendwelchen Auswirkungen.
Die Auswirkungen seien, Auswirkungen im Fehlerfall, Auswirkungen im Lastfall,
das wäre die Effizienz. Und wenn wir da unterscheiden,
mal die, mal die verwenden wollen, dann brauchen wir genau diese Polymorphie,
die wir vorhin hatten und das Dynamische Binden, um dabei Austausch haben zu können.
So, wir bilden Typ Hierarchien, in dem wir super
und Subtypen oder Oberklassen und Unterklassen zusammenbinden, in Beziehung zueinandersetzen. Ja,
die Unterklasse muss dabei, und jetzt kommen wir zu Regeln,
die man einhalten muss für gute Hierarchien, für gute Generalisierungs-,
Spezialisierungshierarchien, die Unterklasse der Subtyp muss typischerweise alle Operationen,
mindestens alle Operationen,
das darüber liegenden Supertyps anbieten und er darf weitere anbieten
Wenn er mindestens die alle anbieten kann, dann kann er auch dafür eingesetzt werden.
Das heißt, alles, was das Konto an Operationen anbietet,
bietet auch das Sparkonto ein, plus ein paar mehr.
Und manche können ein bisschen anders sein,
aber ich kann auf jeden Fall überall,
wo Konto verlangt wird, wo Konto akzeptiert wird,
kann ich auch eine Instanz der Klasse,
ein Exemplar der Klasse Sparkonto verwenden.
Ja, so. Und diese Typ-Jerarchien,
die nach diesen Regeln funktionieren,
heißen Subtyping,
Hierarchien und basieren auf so
Typ Polymophie
Soweit dazu, aber jetzt noch ein weiteres Beispiel.
Wir hatten eben schon das mit dem netten Konto und dann
hatten wir das mit den Collections und jetzt noch etwas aus einem anderen Bereich von Java-Klassenbibliotheken.
Wir hatten beim letzten Mal über Fehler gesprochen,
da war der Begriff Error gefallen und ich hatte sich darauf hingewiesen,
ja, das bedeutet nicht das, was im englischen Error ist,
sondern Error stand für Klassen von Fehlern, also eigentlich für Fehlerereignisse.
Jede Exemplar, die dieser ganzen Klassen, hier ist ein Ereignis,
ein Fehlereignis, das war Stand für Fehlereignisse,
die der Benutzer nicht behandeln kann oder braucht,
weil sie einfach Systemfehler sind,
wo man nichts tun kann,
außer Notabprobleme
Sozusagen. Ja, und die, wo man als Entwickler etwas tun kann,
die sind Exemplare der Klasse oder Instanzen der Klasse Exception.
Und Srobel ist der Oberklasse von allen Throwen Exception,
ist so ein Ereignis erzeugen, so eine Ausnahme hervorrufen.
Und diese Exceptions haben wieder mehrere Unterklassen und ich möchte jetzt
hier besonders auf den Punkt hinweisen,
ich kann so eine Klassenbibliothek durch eigene Klassen erweitern.
Ja, und geprüfte und ungeprüfte Exceptions dabei, darauf gehen wir nochmal ein,
wenn wir, wenn es um uns um Exceptions geht.
Ja, und damit haben wir letztlich auch die Möglichkeit,
das Verhalten zu steuern, indem zum Beispiel hier alle Reaktionen,
alle Fehlerreaktionen, wir sagen dazu Händler, also etwas,
was das behandelt.
Alle Fehlerbehandlungen, die dafür gelten, die passen für das
und die passen für das und die passen für alle Unterklassen.
Und so nutzt man die Java Hierarchie auch
gleich um die Fehlerbehandlung zu strukturieren. Also,
dass ein Beispiel für Typen und die Operationen,
die hier definiert sind,
das ist dann
die Fehlerbehandlung
Wir hatten jetzt gesagt, mehrfach,
es gibt hier Kotwiederverwendung und diese Kurtwiederverwendung ist ja eines der Sachen,
die man als, klassischerweise als wichtigen Bestandteil,
als wichtiges Konzept für ein Objektorientierung betrachtet.
Ja, und die Oberklasse gibt Dinge weiter, unter anderem
den Quellcode weiter. Ja, also die Klasse Konto,
die hat definiert einiges und Sparkonto und Tageskonto können das einfach übernehmen.
Aber da die Unterklassen typischerweise eine Spezialisierung darstellen,
kann man
das anpassen
Definieren, redefinieren, überschreiben, erweitern.
Das sind Begriffe, die wir gleich nochmal haben werden.
Und man könnte das auch so machen, dass man Quelltexte kopiert.
Das passiert hier jedenfalls nicht. Aber in Java ist das
dynamische Binden das Wichtige. So, wir haben als Begriffe
bis jetzt schon gehabt, Ober- und Unterklasse.
Das ist ganz klar, was ist oben aus unten.
Oberklasse ist also das allgemeinere Unterklasse, das Speziellere.
Subtyp und Supertyp passt nicht nur für klasse, passt auch für Interface,
also das verfeinerte und das Allgemeinere und hier der Begriff unmittelbar.
Das Ganze ist transitiv im Sinne von, es setzt sich fort.
Also das heißt, C ist nicht nur Subtyp von B,
sondern auch noch über B hinweg Subtyp von A. So,
soweit diese Begriffe, ich möchte Sie noch darauf hinweisen,
es gibt da auch noch die Mehrfachvererbung.
Ja, Mehrfachvererbung ist etwas, was wir in Java nicht haben.
Nur zwischen Interfaces als Typvererbung und zwar deswegen weil Mehrfachvererbung ein bisschen schwierig ist.
Einfach Vererbung ist relativ klar, die Übergriff,
es gibt eine Oberklasse und davon kann ich mir etwas ableiten,
kann ich etwas erben, das Ganze ist baumförmig.
Um die Mehrfachvererbung gab es tatsächlich in den, in den Jahren,
als die Objektorientierung aufkam, als es ein Hype war,
ganz viel Diskussionen, sollte man das erlauben,
sollte man das nicht erlauben, die Sprache Java hat erlaubt,
das zum Beispiel nicht, die Sprache Ceples Blues erlaubt das und sagt,
ja, wir können doch das nicht verbieten, so ein wichtiges Konzept.
Tatsächlich ist es in gewissen gewisser Weise gefährlich.
Es hat mehrere Probleme, das größte Problem ist eine Namenskollektion,
Kollision, sorry, dass man da einen Konflikt hat.
Auf jeden Fall gemeinsam ist, wir geben Merkmale weiter. Egal ob eins oder mehrere. So,
dass zum Beispiel der Namenskollision hier mal auf dieser Folie,
nehmen wir mal an,
ich habe zwei Oberklassen A und B und ich habe überall eine Methode,
sagen wir mal, Ed heißt die, hier steht nur Arbeit,
sagen wir mal, das wäre die Methode Ed,
wie wir sie eben für die Collectionsklassen hatten.
Und ich möchte hier unten eine Methode Ed erben.
Und wenn ich das dem Compiler sage, hat der Compiler
ein kleines Problem. Der weiß nämlich nicht,
ob er das Ed von hier oder von hier
nehmen muss
Als Mensch, spreche ich ganz selten mit Compilern,
sondern ich teile dem das über Quellcode mit und ich muss also in irgendeiner Weise das steuern.
Ja, also das ist deswegen hier eine Kollision,
der Compiler weiß erst mal selber nicht, was er machen soll. So,
jetzt sind wir soweit erst mal an einem Punkt erreicht,
wo wir mal kurz zusammenfassen können, Vererbung ist so wichtig,
ja, es ist aber auch gefährlich, manche verstehen das,
Miss und wir haben diesen Begriff mehrfach, mit mehrfachen Bedeutungen,
wir haben die Typvererbung, die Implementationsvererbung, also mehrere.
Solche Sachen und Tysubtyp politisch Morphie, hilft uns Hierarchien zu bilden,
Implementation hilft uns tatsächlich, erlaubt uns auch, Quelltexte zu kombinieren.
Wir sollten das voneinander trennen können,
weil das eine und das andere haben unterschiedliche Einsatzgebiete.
Praktisch kommt es ganz häufig gemeinsam vor. Damit wir das richtig machen,
wir hatten ja eben gesagt, es ist schwierig und missverstanden,
das ist jetzt der Kern dieses Abschnitts,
lassen Sie uns diskutieren, wie machen wir es richtig.
Wir sollten das versuchen, nach Ihrer fachlichen Bedeutung
zu machen
Wir sollten erklären, welche, wie funktioniert das technisch,
das Vertragsmodell wird dann im nächsten Abschnitt das Thema sein.
Wenn wir nochmal drüber sprechen, was gut und schlecht ist,
dann zunächst, dass mal die allgemeinen Sachen nochmal,
wir setzen die Elemente, die Typen zueinander in Beziehung,
und zwar hierarchisch, dass wir von oben nach unten anfangen,
oben sind die allgemeinen, unten sind die Spezielleren,
und das Ganze ist eine, ist Einbeziehung.
Ja, und wir sollten dabei darauf achten, dass wir
fachliche Hierarchien bilden, die am Ende in den Typhierarchien landen.
Und dabei ist dieser Ersetzbarkeit, von der wir eben gesprochen haben, besonders wichtig.
Das heißt, die Unterklasse sollte jeweils in der Lage sein,
die Oberklasse zu ersetzen. Das ist hier also für Sparkonto,
sollte Konto ersetzen können. Nun, zu den Gefahren von Vererbung,
ich springe mal kurz, zeige Ihnen nochmal die Frage,
das war die Frage 4, die damit zu tun hat.
Wir kommen gleich hierher zurück,
also auf der Folie mit der Nummer 4 war das hier
diese Frage,
Beispiel für schlechte Wiederverwendung
Das ist hier als Gefahr dargestellt, ja,
und zwar die Gefahr besteht darin, dass wir Abhängigkeiten erzeugen,
die eigentlich keine fachliche Bedeutung, denen keine fachliche Bedeutung dahintersteht.
Diese Abhängigkeiten sind vor allen Dingen dadurch,
treten vor allen Dingen dann auf, wenn,
oder die ungewollten Abhängigkeiten, wenn es nicht zwischen diesen Klassen,
von denen wir Vererbung gerade einführen, Implementationsvererbung einführen,
dass es da keine Abstraktion oder Verallgemeinungs- oder Subtypbeziehung gibt.
Ja, wir haben gleich
ein Beispiel dazu
Man kann das häufig daran erkennen, dass argumentiert wird,
ja, wir wollen dort Code wieder Verwendung machen.
Das ist eine Gefahr,
wenn jemand nur diese Argumente hat und nicht wirklich damit kommt,
dass es fachlich zusammengehört im Sinne von Verallgemeinung, Subtyping.
Ja, wir sollten deswegen unterscheiden, die Konzepte,
diese Subtyping der Verallgemeinung zur Zusammenfassung von Gemeinsamkeiten,
die eigentlich durch Vererbung gestützt werden und Mechanismen, um fremden Code einzubinden.
Das Ganze sollten wir nicht miteinander vermischen. Ich bringe ein Beispiel,
um das zu erläutern, was wir mit fachlich meinen,
ein Beispiel aus dem Bürokonzept Text.
In dem Büro geht es um Dokumente,
die haben wir jeweils hier drin als Operationen angegeben.
Und diese Dokumente, die, mit denen mache ich etwas.
Ja, ich staple die zum Beispiel. Sie wissen,
so ein Stapel im Programmieren mit Stack, das nehme ich als Zwischenablage.
Ich packe was drauf, hole mich gleich weitermachen möchte,
bevor ich zur Mittagspause gehe, bevor ich was Wichtigeres mache.
Oder irgendwie lege ich Zeug auf den Stapel,
die Stapel hat also auf jeden Fall eine Reihenfolge erdient zur Ablage.
Es gibt auch die Ablage selber,
da kann ich etwa Dokumente reintun,
ich glaube in Dokumente
wieder rausnehmen,
Dokumente auswählen
Ordner, da sind auch Dokumente drin, aber die sind beschriftet,
die haben ein Inhaltsverzeichnis und zwischen den verschiedenen Abschnitten gibt es
irgendwie hier eine Trennung, ein Trennblatt oder was auch immer.
Und dann gibt es noch Boxen,
wo ich einfach nur Zeug irgendwie reinpacke, um sie aufzubewahren.
Und da schreibe ich noch dran, was es eigentlich ist.
Soweit erst mal, das können wir sagen, ja,
das sind die Dinge, die wir in so einem Bürokontext mit Dokumenten machen.
Und jetzt lassen Sie uns das mal zu einer Hierarchie von
Subtypes,
Subtyping Hierarchie machen
Hier ist es, wir schauen uns an, ja,
was ist denn das Gemeinsame,
das Gemeinsame war alles das, was bei Ablage geht.
Ich gebe mal mal eine Folie zurück und wieder vor.
Ja, also hier, das war schon blau gekennzeichnet,
das, was sie alle drei gemeinsam haben,
das ist auch gerade das, was Ablage hat.
Also sollten wir doch davon ausgehen, Ablage ist die gemeinsame
Oberklasse, ist der fachliche Oberbegriff. So,
dann gab es unter Ablage noch Sachen, die was Spezielles hinzufügen,
ganz so wie das beim Subtyping machen,
die spezielleren Sachen sind dann hier unter in den Unterklassen,
Ergänzt. Ja, also beim Stapel kann ich was drauflegen, beim Boxtraining beschriften.
Hier kann ich auch beschriften. Ich gehe mal wieder eins
zurück. Dieses Beschriften gab es hier und hier. Ja,
deswegen, dieses mit Textbeschriften kann ich ja dann,
verleitet mich dazu, dass ich das hier zu einer Klasse mache,
die hier so dazwischen hängt.
Ja, die Klasse Box macht dieses mit Textbeschriften und bei Ordner
wird das hier wieder durch Vererbung übernommen bzw. durchs Subtyping.
Ja, soweit ist doch alles gut,
Tatsächlich ist technisch das korrekt, wenn ich das implementiere,
habe ich hier unten alle Operationen, die ich brauche.
Hier habe ich alle Operationen, die ich brauche.
Hier habe ich alle. Und hier habe ich auch Operationen,
die ich brauche, weil ich immer das von oben übernehme.
Aber fachlich ist das nicht okay,
weil wenn sie da jemand mit jemandem mit jemandem sprechen aus diesem Kontext,
der wird ihnen sagen, nee,
ein Ordner ist nicht eine spezielle Box,
das ist irgendwie anders.
Ein Ordner ist was anderes. Ja,
und tatsächlich hätten wir das ein bisschen anderes modellieren müssen,
zum Beispiel indem wir hier noch eine abstrakte Klasse,
ein abstraktes Konzept einfügen,
Ja, etwas aufbewahren, beschriften, auf lange Zeit,
während der Stabe doch eher für Putze auf Bewahrung gedacht ist.
Und da gibt es,
als für ungeordnete Ablagen der Box und für geordnete Ablagen,
die in Ordnung, die zwischendrinblättern und so weiter.
Und das wäre fachlich besser. Und das ist das,
was wir erreichen wollen. Das ist das, wo gute,
gute Klassenhierarchien, Typ Hierarchien entstehen. Und wenn wir das im Großen haben,
hier ein paar mehr solche Punkte, ja,
hier können wir das Schriftgut darstellen,
hier können wir die Ablagen darstellen,
dann muss ich das,
was wir eben hatten
Wir noch fachliche Werte darstellen. Immer können wir Hierarchien bilden,
um solche Typen nach allgemeinerem, spezielleren Sachen zu ordnen.
Und das hilft uns nicht nur, das klar zu trennen,
wir kriegen nicht nur einen Preis für Schönheit, sondern insbesondere, wenn wir etwas ändern.
Sie ändern sich hoffentlich an die erste Vorlesung,
als ich davon gesprochen habe, wie viel sich immer ändert.
Also Veränderbarkeit ist ganz wichtig und die Verständlichkeit. Ja,
also wenn ich dann hier etwas ändere,
wenn sich etwas ändert, wird mit den Unterschriften zum Beispiel,
wir haben jetzt digitale Unterschriften mit irgendeinem,
mit irgendeinem Key Value Paar, ja, unter Verschlüsselung,
dann trifft das auf diese drei Dokumente zu.
Ich brauche es nur einmal ergänzen. Wenn was hier zutrifft,
muss ich es nur hier machen. Und die anderen sind nicht betroffen.
Also die Hierarchie hilft mir, Änderungen effizient zu machen.
Soweit dazu nur noch zu ein paar mehr Begriffen.
Wir hatten vorhin eine ganze Reihe von Begriffen.
Und die möchte ich hier auf dieser Folie nochmal darstellen.
Wir hatten unter anderem den Begriff überladen.
Den habe ich hier einfach nur mal mit reingenommen. Ja,
dass ich also eine zusätzliche Operation anbiete mit gleichem Namen.
Hat eigentlich nicht dioplektier was mit da zu tun, es ist ein bisschen ähnlich.
Also zum Beispiel der Konstruktor von der Klasse Konto,
den kann ich auch als Konstruktor parameterlosen Konstruktor,
das ist der Standardkonstruktor, als Konstruktor mit dem Parameterbetrag und Startguthaben haben.
Also der Typ. So, redefinieren,
das war der eine Begriff, den wir hatten bei dem Subtyping,
ja, da kann ich eine Methode noch einmal definieren.
Die Silberé steht für nochmal und damit ändere ich am Ende
die Implementation
Ich habe eine andere Methode für diese Operation, obwohl sie
schon implementiert war. Und das Beispiel hatten wir schon,
als wir dieses Konto hatten mit der Bucher.
Ja, also ich springe noch mal dahin zurück.
Moment, und zwar zur Folie mit der Nummer 16,
wo wir dieses Polymorphie- und dynamisches Binden erklärt hatten.
Hier gab es in der Oberklasse die Operation,
die Methode buchen und in der Unterklasse haben wir
diese Methode wieder benutzt und haben sie aber überschrieben.
Ich hätte darüber gesprochen, wir sehen zwar hier nicht den Quelltext,
aber ich hatte darüber gesprochen,
dass ich das Verhalten unterscheidet
Soweit dazu. So, zurück zur Folie mit der Nummer 41.
Hier gibt es noch ein anderes Beispiel auf dieser Folie.
Eine Operation, Equals von Object, wie sie sich hoffentlich erinnern.
Alle Klassen in Java, Erben von Object,
als der allgemeinen Oberklasse. Und das ist dann eine Frage,
die ich gerne mit Ihnen wieder in der Fragerunde klären möchte.
Welche mit Operationen sind denn das, die eine Klasse von Object erbt?
Jedenfalls Equals gehört dazu, so viel sehen wir von dieser Folie.
Und wenn ich eine eigene Methode mache,
die natürlich auch von Object erbt,
dann sollte ich die Klasse Equals erneut beschreiben sollte, sie redefinieren.
Ja, also ich schreibe die Methode nochmal neu für meine Klasse.
Es gibt auch noch Redeklarieren, auch wieder etwas mit Reh.
Ich mache eine neue Deklaration und damit ändere ich die Signatur.
Wir setzen auf der folgenden Folie fort, redeklarieren ist in
gewisser Weise gefährlich. Ich sollte nämlich das nur dann einsetzen,
weil ich kann ja im Prinzip alles neu machen.
Ja, wer hindert mich denn dran? Ja,
es sollte aber, es sollte ist immer eine Empfehlung,
ja, also sie merken das schon,
das wird nicht wirklich vom Compiler geprüft werden und eine Fehlermeldung geben.
Man sollte immer dran denken, das sollte ersetzbar bleiben
Und deswegen nur im ganz begrenzten Maße. Der Name sollte gleich bleiben,
die Anzahl und die Reihenfolge der Parameter sollte gleich bleiben.
Ich darf lediglich für die Typen der Parameter oder Ereignisse
was ändern. Soweit. So, weiter geht es dann
mit dem Vertragsmodell. Doch das ist dann
der nächste Abschnitt