Unsere Datenschutzrichtlinie wird in Kürze aktualisiert. Bitte sehen Sie sich die Vorschau an.

Visual C# 2012 Grundkurs

Vererbung

Testen Sie unsere 2013 Kurse

10 Tage kostenlos!

Jetzt testen Alle Abonnements anzeigen
Das Konzept der Vererbung basiert darauf, Code aus einer Klasse in einer anderen zu übernehmen und ausschließlich den Code, welcher sich gegenüber anderer Klassen unterscheidet, zu verändern.

Transkript

In diesem Abschnitt möchte ich Ihnen ein Konzept vorstellen, das sich "Vererbung" nennt. Stellen Sie sich vor, Sie müssten eine Reisekostenabrechnung schreiben. So eine Reisekostenabrechnung besteht aus Kostenpunkten und jeder dieser Kostenpunkte muss mit einem Datum, mit einem Text zu diesem Kostenpunkt und einem bestimmten Betrag versehen sein. Am Ende braucht man vielleicht noch eine Summe, die dann der Betrag ist, der erstattet werden soll. Also denke ich, wäre es vernünftig, man fängt mal an, das ganze System mit einer Klasse "Kostenpunkt" zu implementieren. Wie also schon gesagt, die Klasse "Kostenpunkt" hat erstmal einen Text, ein Datum und zuletzt den Betrag. All diese Felder möchte ich jetzt nach außen durch Properties sichtbar machen. Dazu nehme ich ein elegantes Tool her für Visual Studio, das mir solche Properties um die privaten Felder in dieser Klasse herumhüllt. Solche Properties gibt es wie Sand am Meer im Internet. Da brauchen Sie einfach kurz danach suchen, da werden Sie relativ schnell fündig. Jetzt haben wir unsere Klasse "Kostenpunkt" und können jetzt Element von diesem Kostenpunkt anlegen, und können daraus eine Liste machen, die dann für unsere Reisekostenabrechnung brauchbar ist. Also, es geht dann ungefähr so: Ich lege eine "List of Kostenpunkt" an und in diese Liste kann ich neue Kostenpunkte einsetzen. Jetzt legen wir mal so einen Kostenpunkt an und dann sage ich "text =", sagen wir mal, da ist eine Taxifahrt dabei, und "Datum = DateTime.Now". Das ist die Jetztzeit. Dann bräuchte ich noch einen Betrag dafür. Gut, dann haben wir unseren Kostenpunkt fertig. Jetzt kann ich also in diese Liste der Kostenpunkte diesen Kostenpunkt aufnehmen. Weil es so schön war, machen wir noch einen Kostenpunkt, und der Kostenpunkt soll jetzt z. B. eine Kilometerpauschale enthalten. Also, "Text = 'Km-Pauschale'", "Betrag". Jetzt, sagen wir mal, der Satz wäre 33 Cent pro Kilometer und ich sei 110 Km gefahren, dann ist das also jetzt der Betrag. Da muss natürlich ein Punkt statt ein Komma rein. Dann haben wir noch das Datum. Das ist eben auch das Datum von heute. OK, jetzt habe ich eben mal diese 2 Kostenpunkte in der Liste und kann daraus eine Auswertung machen. Machen wir mal eine Foreach-Schleife, die über diese Kostenpunkte iteriert. Mit "String.Format" können wir also zunächst das Datum ausgeben, dann den Text und dann den Betrag. Das Datum wäre also "kp2.Datum", "kp2.Text", "kp2.Betrag". Schön, wir wollen ja noch die Summe berechnen. Also legen wir eine Variable "decimal summe" an. Dieses "m" nach den Zahlen, das bedeutet, dass es ein Literal des Typs "decimal" ist. Also sonst wäre es so, die Null, für sich gesehen, ist ein Integer-Wert, der dann vom System erst in einen Dezimalwert umgerechnet werden muss, und das kann ich gleich verkürzen, indem ich hier das entsprechende Literal als Dezimaltyp angebe. Innerhalb der Schleife kann ich jetzt die Summe um jeweils den Betrag des Kostenpunktes erhöhen. Man sollte natürlich die richtige Variable nehmen, wenn man ein richtiges Ergebnis haben will. Am Ende können wir also den Gesamtbetrag ausgeben und unsere Summe mit auf der Konsole ausgeben. Das war also unsere kleine Reisekostenabrechnung und dann starten wir das Ganze. Jetzt haben wir noch hier ein kleines Problem. Das kommt wahrscheinlich aus diesem "String.Format". Ich habe natürlich nur 3 Elemente, die mit dem Index von 0 bis 2 gehen. Jetzt haben wir unsere Kostenabrechnung am Bildschirm. Auch der Betrag stimmt, soweit ich das im Kopf nachrechnen kann. Was an der ganzen Abrechnung nicht so ganz toll ist, das ist dieser Punkt hier. Ich kann zwar im Programmcode dieses "0.33m * 110m" hinschreiben, aber normalerweise kommt so ein Wert aus der Benutzer oberfläche. In der Benutzeroberfläche könnte der Benutzer nur einen Betrag eingeben für diesen Kostenpunkt. Das heißt, er müsste sich also mit einem Taschenrechner vor den Computer setzen, müsste zunächst einmal seinen Kilometerpauschalenbetrag ausrechnen, um ihn da einzusetzen. Da fragt man sich natürlich unweigerlich, warum nimmt man nicht gleich das Computerprogramm dafür her, damit dieser Kostenpunkt ausgerechnet werden kann? Ich skizziere das mal in einer uneleganten Weise und werde das Programm nachher entsprechend verbessern. Für diesen Zweck lege ich eine neue Varbiale an, und die soll "strecke" heißen. Auch hier gibt es ein Property drum herum. Ich treffe jetzt folgende Vereinbarung: Wenn hier eine Strecke eingegeben wird, die ungleich 0 ist, dann soll davon ausgegangen werden, dass es sich bei diesem Kostenpunkt um eine Kilometerpauschale handelt. Entsprechend kann dann der Text unter "Betrag" angepasst werden. Ich zeige das jetzt gerade mal. Wenn also die Strecke ungleich Null ist, dann gebe ich zurück Kilometerpauschale und beim Betrag eben so etwas ähnliches. Ich berechne also, wenn die Strecke ungleich Null ist, einfach diesen Gesamtbetrag. Auf diese Weise muss der Benutzer einfach nur noch die Strecke eingeben, die er gefahren ist. Alles andere wird dann automatisch erledigt. So, wollen wir einmal schauen, wie weit wir damit kommen. Ich sollte mir jetzt eigentlich diesen Text hier sparen können. Ich sage einfach, die Strecke sei 110 Kilometer, und das Datum müssen wir natürlich angeben. Der Rest müsste durch das Programm automatisch erledigt werden. Also starten wir das Ganze einmal. Siehe da, es funktioniert genauso, wie wir das erwartet haben. Jetzt ist es aber so, es gibt ja nicht nur Kilometerpauschalen, es gibt ja auch Tagespauschalen. Wenn wir jetzt die Tagespauschale auf die gleiche Weise berechnen wollten, dann müssen wir hier zu der Strecke hinzu, müssen wir noch eine weitere Variable anlegen für die Anzahl der vollen Tage, die jemand unterwegs war, damit wir einen Tagessatz mit beaufschlagen können. Sie merken schon, je mehr von diesen Kostenpunktarten dazu kommen, umso unübersichtlicher und komplexer wird diese Klasse "Kostenpunkt". Weil man ja dann in jeder dieser Methoden diese endlosen Fallentscheidungen drin hat. Jetzt haben wir hier nicht nur "if (strecke !=0)", sondern "if (anzahlTage != 0)", und da unten dann eben auch wieder. In einem System, das, sagen wir einmal, noch ein bisschen komplexer ist und noch ein bisschen mehr Informationen verarbeiten kann, da kann es also schnell eine extrem unübersichtliche Angelegenheit werden. Das Ganze schreit eigentlich danach, dass wir nicht nur eine Klasse "Kostenpunkt" haben, sondern dass wir mit verschiedenen Klassen arbeiten. Also, die Klasse "Kostenpunkt" kann ja drin bleiben für freie Kostenpunkte, aber für die Kilometerpauschale z. B. und für die Tagespauschale könnte man durchaus eigene Klassen anlegen. Man sagt ja auch: "Wenn ich ein unterschiedliches Verhalten erwarte, dann brauche ich auch eine unterschiedliche Klasse." Also könnte ich ja jetzt hergehen und könnte Folgendes machen: Ich sage, ich habe hier eine Klasse "Kilometerpauschale", und die hat also jetzt eben diese Strecke. Diese Strecke wickle ich jetzt wieder in dieses Property und dann kann die Kilometerpauschale eben genauso einen Property-Betrag haben. Ich nehme mal diese beiden Sachen. Die kopiere ich mir, weil die bleiben mehr oder minder gleich. Also, das Datum bleibt komplett gleich und hier der Betrag, da kann ich jetzt die ganze Fallunterscheidung rausnehmen. Deswegen habe ich eine neue Klasse überhaupt gemacht. Man kann den Betrag hier nicht setzen. Der Betrag hat also nur noch einen Getter. Damit habe ich jetzt diese Kilometerpauschale und dann kann ich noch eine dritte Klasse machen, die heißt jetzt "Tagespauschale". Hier habe ich also jetzt die "anzahlTage" als Variable. Es ist jetzt so ähnlich wie hier. Ich kopiere den ganzen Kladderadatsch hier mal und sage: anzahlTage * Wie hoch ist denn so eine Tagepauschale? Ich sage mal, 46 Euro. Jetzt haben wir also das ganze System zerrissen. Sie sehen also gleich den Nachteil dieses Systems. Wir haben es praktisch mit einem Coding beim Copy zu tun. Also ein Drittel der Klasse, nehme ich die Geschichte mit dem Datum, wird simpel kopiert. Man stellt sich vor, was passiert, wenn man eine Änderung der Logik braucht, man feststellt, man möchte nicht das Datum, indem auch die Uhrzeit mitinbegriffen ist, zurückgeben, sondern man möchte sicherstellen, dass nur das Datum zurückkommt. Das kann man z. B. mit diesem Property "date". Jetzt muss ich durch alle Klassen durchgehen und muss dann das an der Stelle immer ändern. Das ist natürlich eine mühsame Angelegenheit, und das schreit danach, dass wir die Sache anders lösen. Ich möchte Ihnen aber gerade noch einmal den allergrößten Nachteil dieses Ansatzes zeigen. Nämlich hier, wenn wir Kostenpunkte anlegen, jetzt sind das alles unterschiedliche Klassen. Das heißt, ich müsste hier verschiedene Listen anlegen, also für die freien Kostenpunkte, dann für die Tagespauschalen und für die Kilometerpauschalen gleichermaßen. Das wären 3 Listen, und diese 3 Listen müsste ich in der Schleife oder in 3 Schleifen durchlaufen hier unten, um dann eben die Summe zu berechnen. Aber auch das wäre noch höchst unelegant, weil es ja sein kann, dass ich die Beträge auf der Abrechnung nach Datum sortiert haben möchte, und nicht nach Belegtyp. Das heißt, ich müsste mir dann die Daten, die ich da errechne, in irgendwelchen Zwischendatenstrukturen halten, die ich dann nach Datum sortieren kann. Da merken wir schon, das ist alles irgendwie Quatsch, das müsste anders gelöst werden. Die Lösung dieses Problems ist die Vererbung. Nun komme ich wieder zurück zu meiner Klasse "Kostenpunkt". Ein Kostenpunkt ist ja genau das, es hat ein Datum, einen Text und einen Betrag. So soll es ja dann in der Abrechnung erscheinen. Was liegt jetzt näher, als diese Klasse "Kostenpunkt" in die weiteren Klassen zu übernehmen und nur das, was sich unterscheidet, abzuändern? Das kann man machen in C# eben durch das Konstrukt der Vererbung. Ich kann also sagen, mit so einem Doppelpunkt, die Kilometerpauschale ist abgeleitet vom Kostenpunkt. Damit kann ich dieses ganze Zeug mit dem Datum herauslöschen. Das brauche ich natürlich jetzt noch mal neu, ist ja klar, weil das ist ja meine eigentliche Logik, weswegen ich eine neue Klasse überhaupt haben wollte. Auch hier kann ich diese ganze Datumsgeschichte rausschmeißen. Aber das ist nicht der ganze Vorteil, sondern der Vorteil ist jetzt wieder dadurch, dass alle diese Klassen jetzt Kostenpunkte sind, können sie wieder Variablen vom Typ "Kostenpunkt" zugewiesen werden. Damit kann ich alle Kostenpunkte wieder in einer Liste erfassen. Jetzt brauche ich nur hierher gehen und kann sagen: "Tagespauschale tp = new Tagespauschale()" Jetzt sage ich "tp.Strecke", und "tp.Datum = DateTime.Now". Jetzt kann ich diese "tp" zu den Kostenpunkten hinzufügen. OK, jetzt habe ich hier natürlich einen Unsinn gemacht, das ist ja die Kilometerpauschale. Und die heißt "kmp", damit der Code hinterher klarer ist, genau so. Jetzt brauchen wir eine Tagespauschale "tp", deswegen habe ich jetzt vorhin die Variable da oben umbenannt, damit das Symbol "tp" hier noch zur Verfügung steht. "tp.anzahlTage = 5" und "tp.Datum", das wäre dann der Beginn der Reise oder so. Das ist dann "DateTime.Now". Auch das wird in die Liste der Kostenpunkte hinzugefügt. Jetzt haben wir unsere 3 Kostenpunkte da drin. Jetzt muss ich gerade mal schauen, ich muss nämlich hier diese Strecke noch rausnehmen aus dem Kostenpunkt. Auch hier diese ganze Logik wieder. Das kann alles hier raus. So, wunderbar. Jetzt, wenn ich die Applikation laufen lasse, stelle ich fest, dass ich zwar wunderschön meine 3 Kostenpunkte habe, aber irgendetwas stimmt mit den Beträgen und den Texten nicht. Die Texte sind leer, die Beträge sind Null. Also, um das Phänomen müssen wir uns noch kümmern. Das Phänomen ist das Folgende, dass ich nämlich dem System sagen muss: "Pass mal auf, dieses Property-Betrag, das soll bitteschön dieses Property überschreiben." Ansonsten geschieht nämlich das Folgende, dass dieses Property-Betrag das andere Property nur versteckt. Aber, weil wir hier ja eine Variable vom Typ Kostenpunkt haben, denkt jetzt das System: "Aha, OK, das ist ein Kostenpunkt, wir nehmen dieses Property." Um das zu verhindern, muss ich das Property als "virtual" markieren. Damit sage ich dem System: "Pass auf, andere Klassen können dieses Property überschreiben." Das machen wir hier eben nicht, weil das Datum soll ja nicht überschrieben werden zunächst mal, aber es würde auch nicht schaden, sagen wir mal so. Hier brauchen wir auf jeden Fall das "virtual"-Keyword, weil der Text ja auch überschrieben werden soll. Dann habe ich hier das Gegenstück zu "virtual" und das heißt "overwrite". Also ich sage: "Überschreibe das Property 'Betrag'." Hier sehe ich bei der Kilometerpauschale, da muss ich nämlich noch dieses Property "Text" überschreiben. Das geht im Visual Studio ganz wunderbar, indem man nämlich einfach nur das Wort "Override" tippt. Sie brauchen auch gar nicht das Wort ganz tippen, sondern es reicht meistens schon "ov" oder so, dann würde Ihnen das Wort "override" schon angeboten. Jetzt drücken Sie einmal Return, machen ein Leerzeichen, und jetzt sehen Sie, was Sie alles überschreiben können. Dann wählen Sie irgendetwas davon aus aus der Liste, und Visual Studio setzt Ihnen komplett die Methode oder das Property, das Sie überschreiben wollen, in den Text ein. Genauso ist das hier entstanden, dieses Property-Text. Jetzt kann ich eben schreiben "return 'Km-Pauschale'". Auch hier mache ich mal dieses "override"-Keyword rein und ich überschreibe das Property-Text. Die Setter, die machen in dem Fall nur relativ wenig Sinn, deswegen lasse ich die Sitter hier leer. Falls jemand versucht irgendeinen Wert reinzuschreiben, wird er schlicht weg ignoriert. Jetzt braucht man hier auch nochmal einen Setter. Ich möchte gerade mal zeigen, dass ich hier bei diesem "override" jetzt durchaus in der Lage bin, einmal diesen Setter auch wegzulassen. Also, das ist jetzt einer der möglichen Wege, die wir hier gehen könnten, aber dann würde das System den Setter aus der Basisklasse übernehmen. Das heißt, wenn ich jetzt hier irgendwie z. B den Betrag reinschreiben wollte, das würde funktionieren und in dem Fall würde dieser Code aufgerufen werden. Dann wäre eben diese Betragvariable gesetzt, was in dem Fall aber jetzt eigentlich keine negativen Auswirkungen für unsere Applikation hat. Ich lösche das jetzt wieder raus. Jetzt schauen wir mal, nachdem wir die ganze Sache virtualisiert und überschrieben haben, wie das System funktioniert – und siehe da: Jetzt kommen eben alle Beträge und alle Texte richtig, und wir haben hier unseren Betrag. So soll das System funktionieren. Damit wären wir am Ende dieses Abschnittes. Sie haben das Konzept der Vererbung kennengelernt, sehen, dass das Konzept der Vererbung auf elegante Weise einige Probleme beseitigt, die bei der Programmierung eben auftauchen können. Eines dieser Probleme ist das Coding by Copy, dass ein und dieselben Codestellen immer wieder kopiert werden, statt dass sie einmal definiert und wiederverwendet werden. Das zweite ist die sogenannte Polymorphie. Das ist genau dieses Phänomen, dass ich verschiedene Klassen unter der Fassade eines Kostenpunkts verwenden kann. Also, in diesem Fall betrachtet das System alle verschiedenen Kostenpunkte, egal von welchem Typ, als ein Objekt des Typs "Kostenpunkt" und schert sich nicht darum, wie diese Kostenpunkte implementiert sind. Das ist dieses Vielgestaltige. Das heißt, Sie haben eine Fassade, aber dahinter verbirgt sich etwas Vielgestaltiges. Ja, soweit zum Abschnitt über Vererbung.

Visual C# 2012 Grundkurs

Schreiben Sie eigene Programme in C# und lernen Sie dazu alle Schlüsselwörter und die meisten Konstrukte kennen, um sicher mit dieser Programmierspreche umzugehen.

7 Std. 1 min (44 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!