Das Video kommt von YouTube: erst beim Abspielen verbindet sich die Seite mit YouTube (Google).
Grundlagen der Informatik 2, Vorlesung 8: Zugriffskontrolle
Das Wichtigste aus dem Video
Tipp auf eine Zeit – das Video springt genau dorthin.
Transkriptautomatisch erstellt · 159 Zeilen
- Hallo liebe Fernstuden und herzlich willkommen zur achten Vorlesung zum Kurs Grundlagen der Informatik 2. In dieser Vorlesung werden wir uns mit
- Zugrskontrollen befassen. Sie haben ja bereits in der Vergangenheit gesehen, dass wenn wir Zugriff erlauben wollen auf bestimmte Attribute oder Methoden,
- wir hierfür Schlüsselwörter verwenden müssen, wie beispielsweise public. Und in dieser Vorlesung wollen wir einmal systematisch darüber sprechen,
- welche Schlüsselwörter es gibt und welche Bedeutungen diese in C#ARP haben. Wir beginnen mit der Diskussion der Zugriffskontrolle auf der obersten
- Ebene, auf der Zugriffskontrolle eine Rolle spielt und zwar bei den Namensräumen oder auch in anderen Programmiersprachen manchmal Pakete
- genannt. Also in Java heißen die z.B. Pakete. In C#ARP können Klassen in Namensräumen gebündelt werden. Das heißt, wir können
- Namensrä Räume definieren und darin verschiedene Klassen anbieten. Wir definieren einen Namensraum über das Schlüsselwort Namespace, das oberhalb
- der Klasse angegeben werden muss. Also, wenn wir eine Klasse in einen Namespace packen wollen, dann müssen wir oberhalb der Klasse schreiben Namespace und dann
- den Namen des Namensraums schreiben. Namespaces dienen dazu, dass man einen Gültigkeitsrahmen für Namen festlegen kann. Also, wenn wir einen Klassennamen
- verwenden innerhalb eines Namensraums, dann kann es nicht eine zweite Klasse haben, die den gleichen Namen trägt im gleichen Namensraum. Aber wenn wir einen
- anderen Namensraum nutzen, dann können wir den gleichen Namen wieder verwenden. Das heißt, wenn wir einen ersten Namensraum A haben und einen zweiten
- Namensraum B haben, dann können wir sowohl in A als auch in B verschiedene Klassen namens vielleicht K haben, also der gleiche Name für die Klasse, sowohl
- in Namensraum A als auch in Namensraum B. Und diese beiden Klassen haben dann nichts miteinander zu tun. Wohingegen, wenn man innerhalb eines Namensraums
- arbeitet, dann kann es immer nur eine Klasse mit einem Namen geben. Nun ist es aber natürlich so, dass man äh eventuell nicht nur innerhalb eines
- Namensraums arbeiten möchte und man kann auf Klassen anderer Namensräume zugreifen. Wir können das entweder machen, indem wir die Namensräume
- explizit vorher erwähnen, also wenn wir jetzt z.B. Beispiel von vorhin nehmen, dass wir in Namensraum A und in Namensraum B jeweils eine Klasse K
- haben. Dann können wir sowas schreiben wie A.K oder B.K, und K, um auf die jeweilige Klasse aus dem Namensraum A oder B zuzugreifen. Außerdem können wir
- auch sagen, dass wir einen Namensraum komplett einbinden. Dafür können wir oben in der Klassendatei schreiben using und dann den Namen des jeweiligen
- Namensraums. Dadurch wird die Klasse, in der wir gerade arbeiten, nicht in den Namensraum hinzugefügt, aber wir können alle Klassen, die in diesem Namensraum
- definiert sind, anschließend verwenden, als wären sie im gleichen Namensraum. Das heißt, wir müssen sie nicht mehr qualifizieren. Wir könnten also, wenn
- wir den Namensraum A einbinden, einfach den Namen K verwenden, ohne dass wir sagen, dass wir das K aus Namensraum A nehmen. Zumindest solange wir nicht auch
- noch einen anderen Namensraum einbinden, indem der gleiche Name auch definiert wird. Schauen wir einmal ein Beispiel dafür
- an, wie ein Namensraum eingebunden wird. Wir definieren hier eine Klasse Order in dem Namensraum Customer und wir wollen in der Klasse Order die Klasse Article
- List nutzen. Und die Klasse Articleist ist aber nicht Teil des Nampaces Customer, sondern des Namensraums Flowershop. Was wir also machen können,
- ist, dass wir oben eine Using Direktive angeben und wir sagen using flowershop.articlist. Wenn wir das machen, dann können wir im
- Rest der Datei auf den Namen Articellist zugreifen, ohne da jeweils Flowershop davorzuschreiben. Das sehen wir hier jetzt in dem
- Beispielscode. Was wir auch tun könnten, wäre den gesamten Namensraum Flowershop einzubinden. Dann würden wir einfach nur schreiben using Flowershop. Allerdings
- hätte das zurfolge, dass wirklich alles, was in dem Namensraum ist, eingebunden würde. Und das hieße jetzt für uns hier, dass wir bei unserer Namensgebung darauf
- achten würden, dass wir nicht nur keine Kollision zu den konkret eingebundenen Klassen haben, sondern dass wir keine Kollision zu irgendeiner Klasse in dem
- Namensraum haben. Und darum ist es häufig besser, wenn man nur einzelne Klassen einmittet, zumindest wenn man nicht sowieso sehr viel Funktionalität
- aus dem anderen Namensraum benötigt. Hier sehen wir jetzt noch einmal, wie das dann tatsächlich aussieht im Code. Wenn wir einen ganzen Namensraum
- einbinden, dann schreiben wir also so etwas wie hier using Flowershop und ansonsten ändert sich im Vergleich zu unserem vorherigen Code nichts.
- Eine wichtige Sache, die vielen Menschen erst einmal nicht klar ist und vielleicht sogar unintuitiv erscheint, ist der Umstand, dass Unternamensräume
- separat importiert werden müssen. Das heißt, wenn wir hier so zwei Zeilen haben, using A und using A.B. B, dann ist die zweite Zeile nicht redundant.
- Der Unternamensraum B von A wird nicht automatisch mit eingebunden, wenn wir den Namensraum A entbinden.
- Bevor wir jetzt zu den Zugriffsbeschränkungen kommen, die für uns eine größere Rolle spielen, nämlich von den Bestandteilen einer Klasse,
- wollen wir zunächst einmal erklären, warum macht man das überhaupt mit Zugriffsbeschränkung, denn man könnte ja in seinem gesamten Code einfach alles
- auf public setzen und dadurch überall maximale Sichtbarkeit haben. Und das tut man aber nicht. Warum denn nicht? Zunächst einmal wäre da die Kontrolle
- des eigenen Zustandes oder auch die Koherenz. Das heißt, wenn wir keinen wahllosen Zugriff von überall her auf unsere Attribute zulassen, dann haben
- wir mehr Kontrolle darüber, welche Werte Attribute einnehmen können. Insbesondere können Setter dazu verwendet werden, auch zu überprüfen, ob ein neu gesetzter
- Wert für ein Attribut überhaupt zulässig ist. Wohingegen, wenn wir ein Attribut einfach nach außen bekannt geben, dann kann jede andere Codeelle unsere
- Attribute auf irgendeine Weise verändern und gegebenenfalls daranhängende andere Attribute nicht berücksichtigen oder sogar illegale Werte für unser
- zusetzenes Attribut setzen. Außerdem haben wir eine größere Unabhängigkeit von der Implementierung, denn wir könnten uns z.B. entscheiden, dass wir
- eine Variable, die wir bisher verwendet haben, als Attribut abschaffen und daraus ein abgeleitetes Attribut machen. Also kein echtes Attribut mehr, sondern
- einen Wert, der jedes Mal, wenn er abgefragt wird, über den Getter neu berechnet wird. Wenn wir allerdings unsere Variablen sichtbar machen nach
- außen, dann können wir das nicht mehr ohne weiteres machen. Denn wenn wir jetzt ein Attribut entfernen und ersetzen durch ein abgeleitetes
- Attribut, dann hat das Zufolge, dass von außen das Verhalten nicht mehr so aussieht, wie es vorher aussah und da müssen wir gegebenenfalls auch anderen
- Code noch mitändern. Außerdem haben wir eine höhere Übersichtlichkeit des Interfaces und der Dokumentation, denn eine Methode, die
- von außen nicht gesehen wird, die muss auch nicht erläutert werden, jedenfalls nicht nach außen erläutert werden. Und das Interface wird dadurch schlanker,
- weil Methoden, die für Außenstehende vielleicht überhaupt keine Relevanz haben, für diese auch nicht sichtbar werden. Und das heißt, wenn Sie dann
- z.B. Codevorschläge bekommen, weil sie mit einem Punktoperator eine Methode auswählen wollen, dann werden auch nur solche Methoden
- vorgeschlagen, die für sie überhaupt eine Rolle spielen. Und wir können all diese Punkte bereits zur Kompilationszeit
- sicherstellen. Das heißt, wir sorgen damit auch dafür, dass wir bestimmte Aufgaben, die sich ansonsten ergeben würden, aus der Testphase oder aus der
- Verifikationsphase des Programms nach vorne ziehen können, sodass wir bereits zur Kompilation feststellen können, dass bestimmte Dinge nicht passieren können.
- Beispielsweise oben, was wir angesprochen haben, dass ein nichtkohärenter Zustand eines Objekts von außen her induziert wird.
- kommen wir dazu, welche Sichtbarkeiten wir beschränken wollen. Und da gibt es im Grunde drei Stellen, an denen wir Sichtbarkeiten gegebenenfalls
- modifizieren wollen. Das wären Klassen, Methoden und Attribute. Wobei wir sehen werden, bei Klassen ist es hier scharf bezüglich der Sichtbarkeit nicht so viel
- zu machen. Bezüglich Methoden und Attributen haben wir aber einige Möglichkeiten, die wir auch kennenlernen und nutzen sollen. Bei den Klassen gibt
- es nur zwei Stufen von Sichtbarkeit und das wäre einmal die Standardsichtbarkeit, die erfolgt, wenn man einfach überhaupt keinen
- Zugsmodifikator angibt und andererseits die public Sichtbarkeit. Dafür müssen wir den Zugsmodifikator public angeben. Die Public Sichtbarkeit bedeutet, dass
- man wirklich von überall aus die Klasse aufrufen kann. Insbesondere und das ist der entscheidende Unterschied von jedem Assembly aus. Das heißt, wenn wir unser
- Assembly beispielsweise als DLL anbieten, dann kann von einem anderen Assembly aus auf diese Klassen, die als public markiert sind, zugegriffen
- werden. Für Klassen, die die Standardsichtbarkeit haben, ist ein solcher Zugriff in einem anderen
- Assembly aber nicht möglich. Und das ist auch der einzige Unterschied. Innerhalb eines Assemblies können wir auf Klassen mit der Standardsichtbarkeit frei
- zugreifen. Die einzige Voraussetzung ist das, was wir oben bereits besprochen haben, dass also wir entweder uns im gleichen Namensraum befinden, den
- entsprechenden Namensraum ausdrücklich einbinden oder aber einen qualifizierten Aufruf an die Klasse durchführen, also mit einem Punkt nach dem Namensraumen
- und dann erst den Namen der Klasse angeben. In Java ist die Standardsichtbarkeit der Klassen auf das Paket und das ist das
- Äquivalent des Namensraumes beschränkt. Eine solche Sichtbarkeitsklasse für Klassen gibt's in C#ARP nicht. Das heißt, wir können nicht sagen, diese
- Klasse kann nur innerhalb unseres Namensraums verwendet werden. Denn wenn wir eine Klasse definieren, haben wir gerade gesehen, dann ist sie ja
- mindestens mit Standardzugriff ausgestattet und dann können wir von jedem Namensraum im gleichen Assembly drauf zugreifen. In diesem Kurs werden
- wir uns aber nicht um das Einbinden von Assemblies, also DLLs kümmern. Und das bedeutet, für uns macht es überhaupt keinen Unterschied, ob eine Klasse
- public ist oder nicht. Sie sollten das grundsätzlich im Kopf behalten, denn wenn sie später produktiv arbeiten, könnte es durchaus mal passieren, dass
- sie mit Assemblies arbeiten. Aber für unseren Einführungskurs hier spielen Assembleys keine Rolle. Es gibt einen Zusammenhang zu dem
- Masterkurs moderne Methoden der Softwareentwicklung. Public Klassen sind solche, die dort veröffentlichte Schnittstellen genannt werden,
- wohingegen die Standardsichtbarkeit mit einem in diesem Kurs öffentlich genannten Namen korrespondieren. Das heißt, ein
- Interface, das als öffentlich bezeichnet wird in diesem Kurs ist das, was wir hier mit der Standardsichtbarkeit auffassen und das, was sogar fair
- öffentlicht ist, sind diejenigen Klassen, die wir hier als Public Kennzeichnen. Wenn wir die Sichtbarkeit von
- Klassenelementen besprechen wollen, dann müssen wir nicht unterscheiden zwischen Methoden und Attributen, denn Methoden und Attribute haben die gleichen
- Sichtbarkeitsklassen zur Verfügung. Diese Sichtbarkeitsklassen, das sind insgesamt sechs Stück, heißen public, protected internal, protected,
- internal, private protected und private. Und wir unterscheiden danach, ob wir aus der gleichen Klasse darauf zugreifen können, aus einer Kindklasse imselben
- Assembly oder in einem anderen Assembly, aus einer nicht abgeleiteten Klasse imselben Assembly oder in einem anderen Assembly. Und wenn wir das Schlüsselwort
- public verwenden, dann bedeutet das, wir können von überall darauf zugreifen. Wohingegen protected bedeutet, wir können von der eigenen Klasse aus darauf
- zugreifen oder von einer Kindklasse, egal ob die im selben Assembly ist oder in einem anderen Assembly. Das Schlüsselwort Internal hingegen
- kümmert sich nicht darum, ob es eine Kindklasse ist, sondern darum, ob wir uns imselben Assembly befinden. Das heißt, internal bedeutet, wir können von
- der gleichen Klasse aus, von der Kindklasse und von nicht abgeleiteten Klassen imselben Assembly auf das entsprechende Klassenelement zugreifen,
- aber nicht in einem anderen Assembly. Wenn man jetzt die Erlaubnisse von Protected und Internal kombinieren möchte, dann kann man den Begriff
- Protected Internal verwenden. Der verbietet dann nur den Zugraff auf dieses jeweilige Klassenelement von einer nicht abgeleiteten Klasse aus, die
- in einem anderen Assembly definiert wird. Wenn man hingegen die Stränge der beiden Elemente protected und internal kombinieren möchte, dann ist Private
- Protected das Richtige. Hier erlauben wir generell gar keinen Zugriff aus einem anderen Assembly und aber auch keinen Zugriff aus nicht abgeleiteten
- Klassen, selbst wenn die im selben Assembly sind. Und schließlich haben wir die letzte Sichtbarkeitsstufe, die auch standardmäßig ohnehin vergeben wird. Das
- ist also hier die Standarddichtbarkeit, das ist private. In der gleichen Klasse können wir damit noch immer auf das jeweilige Klassenelement zugreifen. Das
- lässt sich nie ausschließen, aber keine Kindklasse kann darauf zugreifen und auch keine Nichtkindklasse, egal ob im gleichen oder in einem anderen Assembly
- kann dann darauf zugreifen. Diese Zugriffsmodifikatoren, die wir oben angegeben haben, die werden vor der Deklaration angegeben und sind auch noch
- vor dem Begriffen Static oder Seal zu nennen. Im folgenden beschränken wir uns auf die drei Sichtbarkeitsklassen Private, Protected und Public. Und das
- sind auch die einzigen, die für die Prüfung relevant sein werden, denn wir befassen uns ja in dieser Vorlesung nicht mit Assemblies und die beiden
- anderen Sichtbarkeitsklassen spielen ja hier nur eine weitere Rolle dann, wenn man verschiedene Assemblies betrachtet. Um diese Begriffe ein wenig einzuüben,
- betrachten wir hier einmal ein Beispiel mit drei Klassen A, B und C, wobei B von A abgeleitet ist und C unabhängig von den Klassen A und B ist. Und jede dieser
- drei Klassen hat jeweils ein Attribut. Bei A heißen sie XYZ, bei B heißen sie UVW und bei C heißen sie ABC. Das private protected respektive public ist.
- Beginnen mit der Klasse A. Das Private Attribut X ist nur in A sichtbar, weil ja private bedeutet, dass nur die eigene Klasse es sehen kann. Dann haben wir ein
- Protected Attribut Y. Das ist sichtbar in A und B, denn B ist von Ageleitet. Das heißt, B kann auch darauf zugreifen und schließlich haben wir ein public
- Attribut Z und das ist in allen drei Klassen A, B und C sichtbar, weil es eben public ist und damit keine Einschränkung besteht bezüglich der
- Sichtbarkeit des Attributs. In Klasse B haben wir jetzt UV und W, wobei U private ist und damit automatisch nur in B sichtbar ist. Dann
- haben wir V, das ist protected. Das ist jetzt aber auch nur in B sichtbar, denn B ist zwar vom Aleitet, aber umgekehrt gibt's eine solche Relation ja nicht.
- Wir haben auch keine andere Klasse, die von B abgeleitet ist. Also ist V nur in B sichtbar. Und schließlich haben wir wieder eine Public Variable W und die
- ist in allen drei Klassen sichtbar. Und bei Klasse C stellt sich das jetzt im Grunde genauso da wie bei Klasse B. Wir haben ein private Attribut A, das ist
- damit auch automatisch nur in A nur in C sichtbar. Dann haben wir ein Protected Attribut B. Das ist nur in C sichtbar, denn es gibt keine von C abgeleitete
- Klasse. Und schließlich ein public Attribut, das auch C heißt. Und das ist sichtbar in den Klassen A, B und C, einfach, weil es eben public ist und
- damit keine Einstellung für die Sichtbarkeit besteht. Die Sichtbarkeitsmodifikatoren, die uns in Zuge dieser Vorlesung
- interessieren, nämlich Public Protected Private, lassen sich auch in der UML ausdrücken. Und zwar schreibt man dort die Sichtbarkeitsmodifikatoren, das ist
- jeweils nur ein Zeichen, direkt vor das jeweilige Attribut respektive die jeweilige Methode. Und für public verwenden wir das Zeichen Plus, für
- Protected die Raute und für Private ein Minus. Um das Ganze einmal anhand eines Beispiels zu illustrieren, habe ich hier
- einen kleinen Ausschnitt aus unserer Klassenhierarchie von unserem Leitbeispiel herausgegriffen und diesen Teil des Klassendiagramms
- einmal mit den Sichtbarkeitsmodifikatoren versehen. Wie Sie hier sehen, ist das Ganze im Grunde sehr simpel, denn alle
- Attribute sind hier einfach als private markiert und alle Methoden als public. Das ist nicht zwingend immer so, aber grundsätzlich bietet es sich schon an
- und es ist meistens zu empfehlen, tatsächlich alle Attribute private zu setzen. Und bei den Methoden ist es so, dass normalerweise in einem UML-diagramm
- besonders die öffentlichen Methoden eine wichtige Rolle spielen. Teilweise verzichtet man insbesondere auf die privaten Hilfsmethoden. Also, wenn man
- jetzt eine Methode hat, die nur als Hils Methode verwendet wird, dann ist das für die Modellierung in dem UML-diagramm nicht wichtig. Das heißt, private
- Methoden tauchen hier in aller Regel nicht auf. hingegen protected Methoden spielen natürlich schon eine relevante Rolle und die sind dann auch häufig in
- einem solchen Klassendiagramm zu finden und dann eben zu erkennen, dass da kein Plus steht, sondern eine Raute. Aber die grundlegende Idee ist schon meistens,
- dass man die Attribute nicht sichtbar haben möchte und die Methoden sichtbar haben möchte. Wenn wir einen Klassenmember bei einer
- Vererbung überschreiben und das ist jetzt etwas, was nur Methoden betrifft, dann dürfen die Zugsrechte nur erweitert werden. Das heißt, wir können von
- private zu protected und von Protected zu public übergehen, aber nicht umgekehrt. Das heißt, wenn etwas bereits in der Oberklasse public ist, dann kann
- es in der abgeleiteten Klasse nicht beispielweise auf Protected herabgesetzt werden. Ich habe vorhin bereits einmal angesprochen, dass es grundsätzlich
- sinnvoll und empfehlenswert ist, Attribute private zu behalten und nicht für abgleitete Klassen oder gar außenstehende Klassen sichtbar zu
- machen. Das nennt man auch das Geheimnisprinzip. Und dieses Geheimnisprinzip, das möchten wir jetzt einmal motivieren, indem wir
- ein Beispiel besprechen, bei dem ein echter Vorteil aus dem Geheimnisprinzip erwächst. Man stelle sich vor, man habe eine Klasse Complex Numbers, um die
- komplexen Zahlen zu repräsentieren. Und diese Klasse habe nun zwei Attribute, nämlich den Realteil und den Imaginärteil Real und Imaginary. Die
- haben auch jeweils einen Getter und einen Zter. Jetzt könnte es natürlich sein, dass man sich entscheidet, wir wollen vielleicht
- die komplexen Zahlen gar nicht über Realteilen, die Imaginärteil repräsentieren, sondern viel sinnvoller wäre es doch eigentlich das Ganze über
- Polarkoordinaten zu repräsentieren. Je nachdem, wie man mit diesen komplexen Zahlen rechnet, ist mal die eine und mal die andere Darstellung sinnvoller. Aber
- wenn man z.B. jetzt feststellt die ursprüngliche Idee das über die x und Y Koordinaten zu repräsentieren, also über den realen Imaginärteil, das ist
- meistens jetzt ineffizienter für das, was wir machen wollen. Dann würde man ja vielleicht das Ganze umstellen, würde entsprechend Attribute Radius und Angle
- einfügen und jeweils einen Getter und Zettel dafür angeben. In der Form, die wir gerade gesehen haben, wäre allerdings die Konsequenz
- natürlich, dass das Ganze nicht mehr kompatibel wäre mit Code, der für die alten komplexen Zahlen geschrieben wäre. Was wir aber jetzt tun könnten, ist,
- dass wir die Getter und Zter für die alten Realteile und Imaginärteile hier übersetzen, dass wir also sagen, wir setzen hier gar nicht mehr wirklich
- eine Variable real oder eine Variable Imaginary, sondern wir errechnen, was ist denn die Auswirkung auf Radius und Angle, wenn wir den Realteil oder den
- Imaginärteil separat setzen würden. Das heißt, der Getter ist an der Stelle relativ einfach. Wir rechnen hier einfach über die üblichen Sinus und
- Cosinus Funktionen aus, wie man aus dem Radius und aus dem Winkel den entsprechenden real und Imaginärteil bekommt. Und die Zter, die berechnen
- nun, wie man aus den kathesischen Koordinaten die Polarkoordinaten ermittelt. Das heißt, wir setzen jetzt beispielsweise den Realteil, das heißt,
- wir belassen den imaginärteil unverändert, den nehmen wir uns zunächst einmal mit Get Imaginary. Den berechnen wir also an der Stelle.
- Und dann setzen wir den neuen Winkel und den neuen Radius aus diesen kathetesischen Koordinaten, also aus den Werten Real Imaginary. Und genau das
- gleiche machen wir, wenn der Imaginärteil gesetzt wird. In der obigen Implementation fehlte jetzt noch die vorausgesetzte Methode
- Set from Cartesion. Und diese Methode würde man jetzt üblicherweise private setzen, denn das ist ja nur eine Hilfsmethode für unsere Implementation
- der komplexen Zahlen als Polarkoordinaten. Und diese Methode bekommt also einen Realteil, ein Imaginärteil übergeben und
- berechne ich jetzt einfach den Radius und den Winkel entsprechend der Zuordnungsvorschriften, die üblicherweise verwendet werden, um eine
- solche Transformation zwischen diesen beiden Darstellungen vorzunehmen. Die genauen Formeln müssen sie sich jetzt eigentlich gar nicht groß anschauen an
- der Stelle. Wichtig ist nur, wir verwenden auch hier wieder den Setter. Das heißt, selbst wenn wir uns später entscheiden würden, wieder zu wechseln
- zwischen den Polarkoordinaten und den Realteil und Imaginärteil, könnten wir an der Stelle mit wenig Aufwand diese Methoden immer noch beibehalten.
- Der große Vorteil ist jetzt an der Stelle jedenfalls, dass von außen wir überhaupt nichts verloren haben und sich nichts geändert hat für den Aufrufer,
- indem wir hier die Polarkoordinaten statt der realen Imaginärteile verwendet haben. Das heißt, wenn wir uns jetzt entschieden hätten, realen Imaginärteil
- nicht privat zu halten, dann hätten wir jetzt das Problem, dass wir alle Klassen, die unsere komplexen Zahlen genutzt haben, daraufhin überprüfen
- müssten, ob dort irgendeinen Zugriff auf den realen Imaginärteil stattgefunden hat und das dann jetzt auf unsere Getter und Zter umlenken oder aber komplett den
- Code zu ändern, um direkt mit den Polarkoordinaten zu arbeiten. Das ist natürlich jetzt ein Beispiel, dem dem sie nicht häufig zu tun haben
- werden, dass sie jetzt konkret die komplexen Zahlen implementieren, aber es ist etwas, was immer mal wieder vorkommen kann, dass sie abgeleitete
- Attribute und nicht abgeleitete Attribute haben und zwischen denen wechseln müssen. Üblich schließen wir diese Vorlesungseinheit mit drei Fragen
- zur Selbstdiagnose, mit denen Sie überprüfen können, ob Sie die Inhalte dieser Vorlesung gut verstanden haben. Die erste Frage ist, wozu sollte man
- Zugriffsbeschränkungen vornehmen? Die zweite Frage ist, was gilt für die Zugriffsmöglichkeiten auf Klassen, Attribute und Methoden, wenn man keinen
- Zugriffsmodifikator angibt? Und schließlich, was ist hinsichtig der Sichtbarkeitsklassen bei der Spezialisierung, also der Ableitung zu
- berücksichtigen? Vielen Dank für Ihre Aufmerksamkeit und bis zum nächsten Mal. M.