Difference between revisions of "TU Wien:Objektorientierte Programmiertechniken VU (Puntigam)/Wiederholungsfragen 2019W"

From VoWi
Jump to navigation Jump to search
 
(5 intermediate revisions by the same user not shown)
Line 475: Line 475:
 
* Nachbedingungen (@result, „Was sagt das Ergebnis aus?“)
 
* Nachbedingungen (@result, „Was sagt das Ergebnis aus?“)
 
* Invarianten (Gelten für alle Methoden, Zuständigkeit des Servers)
 
* Invarianten (Gelten für alle Methoden, Zuständigkeit des Servers)
 +
*History-Constraint: schränken die Entwicklung von Objekten im Laufe der Zeit ein.
 +
** Server-kontrolliert: wie Invarianten. Z.B. ganzzahlige Zähler kann im Laufe der Zeit nur größer werden.
 +
** Client-kontrolliert: Reihenfolge der Methodenaufrufe einschränken. Z.B. Methode "Initialize" kann in jedem Objekt nur einmal aufgerufen werden.
  
 
Grundsätzlich ist der Programmierer für die Einhaltung der Zusicherungen verantwortlich.
 
Grundsätzlich ist der Programmierer für die Einhaltung der Zusicherungen verantwortlich.

Latest revision as of 20:13, 28 June 2020

Folgende Fragen sollen beim Erarbeiten des Stoffes helfen. Sie stellen keine vollständige Aufzählung möglicher Prüfungsfragen dar.

Contents

Paradigmen der Programmierung[edit]

1. Was versteht man unter einem Programmierparadigma?[edit]

Eine Bestimmte Denkweise oder Art der Programmierung.

Berechnungsmodell und Programmstruktur[edit]

2. Wozu dient ein Berechnungsmodell?[edit]

Hinter jedem Paradigma ist ein Berechnungsmodell. Es muss turing-vollstandig sein (alle Berechnungen kénnen die auch ein Computer kann) und konsistent

3. Welche Berechnungsmodelle werden in Programmierparadigmen verwendet, und welche charakteristischen Eigenschaften haben sie?[edit]

Funktionen
primitiv-rekursive
Pradikatenlogik
vor allem in Datenbanken
Constraint-Programmierung
x<5 oder A oder B ist wahr (heute werden dafür fertige Bibliotheken verwendet)
Temporale Logik und Petri-Netze
Freie Algebren
stark vereinfachte Algebren (einfache Axiome)
Prozesskalküle
Automaten
werden heute vorwiegend noch wegen der guten verstandlichkeit verwendet
WHILE, GOTO und Co
z.B.: bei MIPS nur LOOP und END LOOP

4. Welche Eigenschaften von Berechnungsmodellen sind für deren Erfolg häufig (mit)bestimmend?[edit]

Universell einsetzbar, Abstraktion, Beharrungsvermögen, konsistenz

5. Im Spannungsfeld welcher widersprüchlichen Ziele befinden sich Programmierparadigmen? Wie äußert sich dieses Spannungsfeld?[edit]

Flexibilität, Lesbarkeit, verständlich (Man will alles beschreiben aber es soll noch übersichtlich bleiben)

6. Was ist die strukturierte Programmierung? Wozu dient sie?[edit]

Besteht aus drei Kontrollstrukturen: Sequenz (eins nach dem anderen), Auswahl (if, else), Wiederholung (Schleife, Rekursion) Bringt Struktur in Programmierung und bessere Lesbarkeit

7. Wie gehen unterschiedliche Paradigmen mit Seiteneffekten um?[edit]

  • Deklarative Paradigmen: radikaler Ansatz = referentiell transparent (f{x)+f(x) = 2 f(x))
  • Objektorientierte Paradigmen: Querverbindungen werden lokal auf einzelne Objekte beschränkt.

8. Was bedeutet referentielle Transparenz, und wo findet man referentielle Transparenz?[edit]

Ein Ausdruck ist referentiell transparent wenn er durch seinen Wert ersetzt werden kann ohne die Semantik des Programms zu ändern (3+4 => 7)

9. Wieso passt referentielle Transparenz nicht gut mit Ein- und Ausgabe zusammen, und wie kann man das Dilemma lösen?[edit]

Weil Ein- und Ausgabe auch Seiteneffekte sind => wird nur ganz oben in der Aufrufhierarchie erlaubt

10. Welchen Zusammenhang gibt es zwischen Seiteneffekten und der objektorientierten Programmierung?[edit]

Siehe 7)

11. Was sind First-Class-Entities? Welche Gründe sprechen für deren Verwendung, welche dagegen?[edit]

Funktionen können wie normale Daten verwendet werden => in Variablen ablegen usw.. Sind komplizierter aber können als Kontrollstrukturen verwendet werden (Funktionen in Funktionen)

12. Was haben Funktionen höherer Ordnung mit einem applikativen Programmierstil zu tun?[edit]

Es können Schablonen mit Löchern geschrieben werden die dann durch die Übergabe von Funktionen (zum Füllen der Löcher ausführbar werden)

Programmorganisation[edit]

13. Welche Modularisierungseinheiten gibt es, was sind ihre charakteristischen Eigenschaften, und wodurch unterscheiden sie sich?[edit]

Objekte
(Zustand, Identität, Verhalten) Daten Kapselung und Data Hiding = Datenabstraktion
Klassen
Schablone für neue Objekte
Komponente
eigenständiges Stück Software dass nur mit anderen Komponenten richtig funktioniert. Bei Übersetzungszeit ist offen von wo importierte Inhalte kommen
Namensraum
fassen Modularisierungseinheiten zusammen ohne die getrennte Übersetzbarkeit zu zerstören. => z.B.: a.b.C (Klasse C im Namensraum b, welcher im Namensraum a steht)

14. Welche Bedeutung haben Schnittstellen für Modularisierungseinheiten? Warum unterscheidet man zwischen von außen zugreifbaren und privaten Inhalten?[edit]

Zusammengefasst Informationen über Inhalte des Moduls, die auch in anderen Modulen verwendbar sind. Private Inhalte können vom compiler beliebig optimiert werden. Von außen zugreifbare können nicht beliebig verändert werden da sie mit anderen Modulen zusammenarbeiten und somit auch die anderen Module geändert werden müssten.

15. Was ist und wozu dient ein Namensraum?[edit]

Ein Namensraum gilt pro Modul. Das heißt die Namen müssen nur in diesem Namensraum eindeutig sein. In anderen Modulen/Namensräumen können dieselben Namen verwendet werden. Beim Import kann man Namenskonflikte durch Umbenennungen vermeiden.

16. Warum können Module nicht zyklisch voneinander abhängen, Komponenten aber schon?[edit]

Weil Module getrennt übersetzt werden. Wenn A von B abhängt muss B vor A übersetzt werden. Wenn jetzt B auch von A abhängen würde hätten wir einen Deadlock. Diese Abhängigkeiten kann man mit der Aufteilung eines Moduls in Schnittstelleninformation und Implementierung aufteilt. (z.B.: Interfaces und Klassen (die die Interfaces implementieren)) Weil bei Komponenten erst zur Laufzeit bestimmt wird von wo importierte Inhalte kommen.

17. Was versteht man unter Datenabstraktion, Kapselung und DataHiding?[edit]

  • Datenkapselung ist die Verschmelzung von zusammengehörigen Daten in eine Einheit.
  • DataHiding versteckt private Inhalte vor dem Zugriff von außen.
  • Datenabstraktion = Datenkapselung + DataHiding

18. Warum und inwiefern ist die Einbindung von Komponenten komplizierter als die von Modulen?[edit]

Während Module getrennt voneinander als eigene selbstständige Einheiten angesehen werden können, interagieren Komponenten untereinander. Außerdem wird bei Komponenten erst zur Laufzeit klar von wo importiert wird.

19. Wie kann man globale Namen verwalten?[edit]

Es wird ganz den Softwareentwicklern überlassen. Man mussalle Dateien anführen die die Modularisierungseinheiten enthalten. Oft helfen standardmäßig vorgegebene Verzeichnisse in denen automatisch nach verwendeten Modul- oder Klassennamen gesucht wird.

20. Was versteht man unter Parametrisierung? Wann kann das Befüllen von „Lücken“ durch welche Techniken erfolgen?[edit]

In Modulen werden Löcher gelassen, die erst später gefüllt werden.

Zur Laufzeit
  • Konstruktor
  • Initialsierungsmethoden (z.B.: beim Kopieren von Objekten)
  • Zentrale Ablage (globale Variablen die erst zur Laufzeit abgeholt werden (z.B.: durch einfachen Zugriff oder Methoden)
Generizität

Füllung der Löcher zur Übersetzungszeit. Man programmiert so dass mehrere Typen verwendet werden können. Einschränkungen lassen sich schwer umsetzen da es sich nicht um First-Class-Entities handet.

Annotationen

@Override etc. Es lässt sich erfragen mit welcher Annotation etwas versehen ist (dynamisch zur Laufzeit) und können so den Programmablauf steuern. Oft wird dieses Konzept eingesetzt wenn Annotationen nicht nur von lokaler Bedeutung sind. (sondern auch Systemwerkzeuge)

Aspekte

Ein Aspekt spezifiziert gewisse Punkte im Programm und was an diesen Stellen passieren soll. Ein Aspect Weaver modifiziert das Programm entsprechend den Aspekten. (z.B.: Debugging, Logging)

21. Warum braucht man zur Parametrisierung in der Objekterzeugung neben Konstruktoren gelegentlich auch Initialisierungsmethoden?[edit]

Weil Objekte auch kopiert werden können.

22. Welche Vor- und Nachteile hat die zentrale Ablage von Werten zum Zweck der Parametrisierung?[edit]

Sie ist auch für statische Modularisierungseinheiten verwendbar die bereits zur Übersetzungszeit feststehen.

23. Was unterscheidet Generizität von den verschiedenen Formen der Parametrisierung zur Laufzeit?[edit]

Löcher werden bereits zur Übersetzungszeit gefüllt.

24. Was sind Annotationen und wozu kann man sie verwenden? Wodurch unterscheiden sie sich von Generizität?[edit]

Die Löcher die durch Annotationen gefüllt werden sind im Gegensatz zur Generizität nirgends im Programm festgelegt => Art und Weise der Verwendung sehr unterschiedlich.

25. Was versteht man unter aspektorientierter Programmierung?[edit]

(siehe Frage 20)

26. Wodurch unterscheidet sich Parametrisierung von der Ersetzbarkeit, und warum ist die Ersetzbarkeit von so zentraler Bedeutung?[edit]

Während bei der Parametrisierung Änderungen an den Löchern auch gleich Änderungen an den einzusetzenden Dingen der Löcher nach sich ziehen, kann durch Ersetzbarkeit einfacher nachträgliche Änderungen einzelner Moduleinheiten erreicht werden.

27. Wann ist A durch B ersetzbar?[edit]

Wenn der Austausch keinerlei Änderungen an Stellen nach sich zieht, an denen A verwendet wird.

28. Wodurch kann festgelegt sein, ob A durch B ersetzbar ist?[edit]

Wenn die Schnittstelle von B dasselbe Beschreibt wie die Schnittstelle von A (aber die Schnittstelle von B kann mehr beschreiben als die von A)

29. Was ist die Signatur einer Modularisierungseinheit?[edit]

Boolean Funktion(int x); => Signatur = Funktion(int)

Boolean Funktion(double x); => Signatur = Funktion(double)

Namen und Typen von Parametern

30. Wie verhält sich die Signatur einer Modularisierungseinheit zur Abstraktion, die durch diese Modularisierungseinheit gebildet wird?[edit]

Zusätzlich zur Signatur werden Schnittstellen durch Namen und informelle Texte beschrieben.

31. Was sind Zusicherungen, und welche Rolle spielen sie für Modularisierungseinheiten?[edit]

Genaue Beschreibung der Ewartung an die Modularisierungseinheiten. Vertrag zwischen Modularisierungseinheit (Server) und ihren Verwendern(Clients).

Vorbedingung
was können sich Server von den Clients erwarten?
Nachbedingung
was kann sich der Client vom Server erwarten?
Invarianten
welche Eigenschaften in konsit. Programmzuständen immer erfüllt sind.
History-Constraints
wie und v.a. in welcher Reihenfolge Clients mir Servern agieren können.

Typisierung[edit]

32. Wann sind Typen miteinander konsistent, und was sind Typfehler?[edit]

Wenn die Typen der Operanden mit den Operationen zusammenpassen. Sonst tritt ein Typfehler auf.

33. Wie schränken Typen die Flexibilität ein, und warum verwendet man Typen trotzdem?[edit]

Die Einschränkung ist, dass wir uns für einen Typen entscheiden und diese Entscheidung zieht sich über das gesammte Programm. Damit sind wir nicht so flexibel wie bei einer dynamischen Sprache(Typprüfung erst zu Laufzeit), jedoch ergibt sich folgender Vorteil: verbessert Lesbarkeit, verbesserte Zuverlässigkeit des Programms.

34. Welche Gründe sprechen für den Einsatz statischer Typprüfungen, welche dagegen?[edit]

Pro: Einmal getroffene Entscheidungen bleiben konsistent. Je früher Entscheidungen getroffen werden desto weniger ist zur Laufzeit zu tun. Typfehler werden früher erkannt, wo die Auswirkungen noch nicht so groß sind. Man ist dadurch aber auch eingeschränkter.

35. Was versteht man unter Typinferenz? Welche Gründe sprechen für bzw. gegen den Einsatz?[edit]

Typinferenz spart das Anschreiben von Typen. Typinferenz und Ersetzbarkeit durch Untertypen verträgt sich nicht. (im selben Teil des Programms). Lesbarkeit kann dadurch sogar verbessert werden weil es nur dort eingesetzt wird wo der Typ eh glasklar ist.

36. Zu welchen Zeitpunkten können Entscheidungen getroffen werden (Typen und Entscheidungsprozesse)?[edit]

Alle bedeutenden Entscheidungen hinsichtlich der Programmstruktur und des Programmablaufs werden jedoch schon vorher, bei der Programmerstellung getroffen. Zeitpunkte:

  • in der Sprachimplementierung z.B. int als 32-Bit definiert
  • Zum Zeitpunkt der Erstellung von Übersetzungseinheiten
  • Entscheidungen durch Parametrisierung erst bei der Einbindung vorhandener Module, Klassen oder Komponenten getroffen
  • Vom Compiler(meist nur Optimierungen)
  • Zur Laufzeit: Initialisierungsphase von der eigentlichen Programmausführung unterscheidbar.

37. Welchen Einfluss können Typen auf Entscheidungszeitpunkte haben?[edit]

Frühere Entscheidungen machen dann zur Laufzeit weniger Arbeit. Sogar wenn man weiß, dass die Variable eine ganze Zahl enthält, muss der Compiler eine beliebige Referenz annehmen und zur Laufzeit eine dynamische Typprüfung durchführen.

38. Wie beeinflussen Typen die Planbarkeit weiterer Schritte?[edit]

Wenn man weiß, dass eine Variable vom Typ int ist, braucht man kaum mehr Überlegungen darüber anstellen, welche Werte in der Variablen enthalten sein könnten. Statt auf Spekulationen baut man auf Wissen auf. Um sich auf einen Typ festlegen zu können, muss man voraussehen (also planen), wie bestimmte Programmteile im fertigen Programm verwendet werden. Man wird zuerst jene Typen festlegen, bei denen man kaum Zweifel an der künftigen Verwendung hat. → frühe Entscheidungen daher oft sehr stabil.

39. Was ist ein abstrakter Datentyp?[edit]

Die Trennung zwischen Innenansicht und Außenansicht einer Modularisierungseinheit (Data- Hiding). Die nach außen hin sichtbaren Inhalte bestimmen die Verwendbarkeit der Modularisierungseinheit. Private Inhalte bleiben bei der Verwendung unbekannt und die gesamte Modularisierungseinheit daher auf gewisse Weise abstrakt. Hinter jeder Modularisierungseinheit steht ein abstraktes Konzept, das im Idealfall eine Analogie in der realen Welt hat.

40. Was unterscheidet strukturelle von nominalen Typen?[edit]

Struktureller Typ
Typ der Modularisierungseinheit hängt nur von Namen, Parametertypen und Ergebnistypen der nach außen sichtbaren Modulinhalte abhängt
Nominaler Typ
Neben Signatur auch einen eindeutigen Namen. Der Typ eines Objekts entspricht dem Namen der Klasse von der das Objekt erzeugt wurde.

41. Warum verwenden wir in Programmiersprachen meist nominale Typen, in theoretischen Modellen aber hauptsächlich strukturelle?[edit]

Man gibt jeder Modularisierungseinheit einen eigentlich nicht verwendeten Inhalt mit, dessen Name das Konzept dahinter beschreibt. Damit werden gleiche Signaturen für unterschiedliche Konzepte ausgeschlossen. Wegen dieser stets vorhandenen Möglichkeit zur Abstraktion werden in der Theorie überwiegend strukturelle Typen betrachtet. Beim Programmieren denkt man hauptsächlich in abstrakten Konzepten und selten an Signaturen daher nominale Typen

42. Wie hängen Untertypbeziehungen mit Ersetzbarkeit zusammen?[edit]

Untertypen werden durch das Ersetzbarkeitsprinzip definiert. Ohne Ersetzbarkeit gibt es keine Untertypen. Faustregel: Ein Typ U ist Untertyp von Typ T wenn jedes Objekt von U überall verwendbar ist, wo ein Objekt von T erwartet wird.

43. Warum kann ein Compiler ohne Unterstützung durch Programmierer(innen) nicht entscheiden, ob ein nominaler Typ Untertyp eines anderen nominalen Typs ist?[edit]

Für nominale Typen reichen einfache Regeln nicht aus. Abstrakte und daher den Regeln nicht zugängliche Konzeptelassen sich ja nicht automatisch vergleichen. In der Praxis muss man beim Programmieren explizit hinschreiben, welcher Typ Untertyp von welchem anderen ist.

44. Erklären Sie Einschränkungen bei Untertypbeziehungen zusammen mit statischer Typprüfung.[edit]

Es gibt keine Möglichkeit, entsprechende Typen statisch zu prüfen. Dynamische Prüfungen sind natürlich möglich. Aus demselben Grund sind auch Wertebereichseinschränkungen im Allgemeinen nicht statisch prüfbar; das bedeutet z.B., dass int nicht als Untertyp von long betrachtet werden kann, obwohl jede Zahl in int auch in long vorkommt.

45. In welchem Zusammenhang verwendet man Higher-Order-Subtyping und F-gebundene Generizität?[edit]

Einfache Generizität ist leicht zu verstehen und auch vom Compiler leicht handzuhaben. Die Komplexität steigt jedoch rasch an, wenn man Einschränkungen auf Typparametern berücksichtigt, die vor allem (aber nicht nur)in der objektorientierten Programmierung benötigt werden. Im Wesentlichen gibt es zwei etwa gleichwertige formale Ansätze dafür: F-gebundene Generizität nutzt Untertypbeziehungen zur Beschreibung von Einschränkungen und wird z.B. in Java und C# eingesetzt. HigherOrder-Subtyping, auch Matching genannt, geht einen eher direkten Weg und beschreibt Einschränkungen über Untertyp-ähnliche Beziehungen, die wegen Unterschieden in Details aber keine Untertypbeziehungen sind.

46. Wie konstruiert man rekursive Datenstrukturen?[edit]

Mittels induktiven Konstruktionen; Mengenvereinigung

47. Was versteht man unter Fundiertheit rekursiver Datenstrukturen? Welche Ansätze dazu kann man unterscheiden?[edit]

Man muss klar zwischen MO (nicht-rekursiv) und der Konstruktion aller Mi mit i > O (rekursiv) unterscheiden, wobei MO nichtleer sein darf. Diese Eigenschaft nennt man Fundiertheit In Haskell muss es in jeder Typdefinition zumindest eine nicht-rekursive Alternative (z.B. end in Lst) geben. Die Menge MO ist etwa in Java schon in der Sprachdefinition vorgegeben und enthält nur den speziellen Wert null

48. Warum wird Typinferenz in objektorientierten Sprachen meist nur lokal beschränkt eingesetzt?[edit]

Typinferenz funktioniert nicht, wenn gleichzeitig (also an derselben Stelle im Programm) Ersetzbarkeit durch Untertypen verwendet wird.

49. Wie können statisch geprüfte Typen beliebige Eigenschaften von Werten propagieren?[edit]

Eine Funktion kann nur aufgerufen werden, wenn der Typ des Arguments mit dem des formalen Parameters übereinstimmt. Dabei wird Information über das Argumentan die aufgerufene Funktion propagiert. Entsprechendesgilt auch für das Propagieren von Information von der aufgerufenen Funktion zur Stelle des Aufrufs unter Verwendung des Ergebnistyps und bei der Zuweisung eines Wertes an eine Variable. Genau diese Art des Propagierens von Information funktioniert nicht nur für Typen im herkömmlichen Sinn, sondern für alle statisch bekannten Eigenschaften.

Objektorientierte Programmierung[edit]

50. Erklären Sie folgende Begriffe:[edit]

  • Objekt, Klasse, Vererbung
  • Identität, Zustand, Verhalten, Schnittstelle
  • deklarierter, statischer und dynamischer Typ
  • Faktorisierung, Refaktorisierung
  • Verantwortlichkeiten, Klassenzusammenhalt, Objektkopplung


51. Welche Arten von Polymorphismus unterscheidet man? Welche davon sind in der objektorientierten Programmierung wichtig? Warum?[edit]

In der objektorientierten Programmierung sind Untertypen von überragender Bedeutung, die anderen Arten des Polymorphismus existieren eher nebenbei. Daher nennt man alles, was mit Untertypen zu tun hat, oft auch objektorientierten Polymorphismus oder nur kurz Polymorphismus.

52. Wann sind zwei gleiche Objekte identisch und wann sind zwei identische Objekte gleich?[edit]

Zwei durch verschiedene Variablen referenzierte Objekte sind identisch wenn es sich um ein und dasselbe Objekt handelt. Zwei Objekte sind gleich wenn sie denselben Zustand und dasselbe Verhalten haben, auch wenn sie nicht identisch sind. In diesem Fall ist ein Objekt eine Kopie des anderen. Zustandsgleichheit: Wenn die Parameter gleich sind (wird mit equals verglichen) Ident: Wenn es sich um das identische Objekt, also das selbe Abbild im Speicher, handelt (wird mit == verglichen)

53. Sind Datenabstraktion, Datenkapselung und Data-Hiding einander entsprechende Begriffe? Wenn Nein, worin unterscheiden sie sich?[edit]

Datenabstraktion und Datenkapselung sind komplimentäre Konzepte: Während sich die Abstraktion auf das von außen sichtbare fokusiert, beschäftigt sich die Kapselung mit der eigentlichen Implementierung, welche die Geheimnisse und Implementierungsdetails oft mit Data-Hiding archiviert.

54. Was besagt das Ersetzbarkeitsprinzip? (Häufige Prüfungsfrage!)[edit]

Ein Typ U ist Untertyp eines Typs T, wenn jedes Objekt von U überall verwendbar ist wo ein Objekt von T erwartet wird.

55. Warum ist Ersetzbarkeit in der objektorientierten Programmierung so wichtig (mehrere Gründe)?[edit]

Eine Möglichkeit zur praxistauglichen nachträglichen Änderung von Modularisierungseinheiten verspricht der Einsatz von Ersetzbarkeit statt oder zusätzlich zur Parametrisierung: Aufgrund der hohen Code-Wiederverwendung. Ohne Ersetzbarkeit keine Untertypen.

56. Wann und warum ist gute Wartbarkeit wichtig?[edit]

Da Wartungskosten ca. 70 % der Gesamtkosten ausmachen. Gute Wartbarkeit erspart Unmengen an Geld! Wenn das Programm öfter verwendet wird

57. Wie lauten die wichtigsten Faustregeln im Zusammenhang mit Klassenzusammenhalt und Objektkopplung? Welche Vorteile kann man sich davon erwarten, dass diese Faustregeln erfüllt sind?[edit]

Der Klassenzusammenhang soll hoch sein & Die Objektkopplung soll schwach sein gute Faktorisierung, Wahrscheinlichkeit geringer, dass bei Programmänderung auch die Zerlegung in Klassen und Objekte geändert werden muss.

58. Welche Arten von Software kann man wiederverwenden, und welche Rolle spielt jede davon in der Softwareentwicklung?[edit]

  • Programme: werden oft genau für häufige (wieder)verwendung entwickelt
  • Daten: oft überdauern Daten die Lebensdauer der Programme.
  • Erfahrungen: können zwischen sehr unterschiedlichen Projekten ausgetauscht werden.
  • Code: Konzepte v. Untertypen, Vererbung und Generizität wurden im Hinblick für Code Wiederverwendung entwickelt. Man unterscheidet folgende Arten der Wiederverwendung: Bibliotheken, Projektinterne- oder Programminterne Wiederverwendung.

59. Welche Rolle spielen Refaktorisierungen in der Wiederverwendung?[edit]

Refaktorisierungen ermöglichen das Hinführen des Projektes auf ein stabiles gut faktorisiertes Design. Gute Faktorisierung => starken Klassenzusammenhalt => gut abgeschlossene und somit leicht wiederverwendbare Klassen. Sie ändert die Struktur eines Programms,lässt aber dessen Funktionalität unverändert. Faustregel: Ein vernünftiges Maß rechtzeitiger Refaktorisierungen führt häufig zu gut faktorisierten Programmen und dadurch zu stabilen Klassen die für Vererbung und Untertypbeziehungen wichtig sind.

60. Wofür ist die objektorientierte Programmierung gut geeignet, und wofür ist sie nicht gut geeignet?[edit]

Wenn Algorithmen zentral im Mittelpunkt stehen ist sie nicht gut geeignet. OOP steht die Datenabstraktion im Mittelpunkt, aber Algorithmen müssen unter Umständen aufwendig auf mehrere Objekte aufgeteilt werden. Das kann den Entwicklungsaufwand von Algorithmen erhöhen und deren Verständlichkeit verringern.

Faustregel: Objektorientierte Programmierung eignet sich zur Entwicklung von Systemen, deren Gesamtkomplexität jene der einzelnen Algorithmen deutlich übersteigt. Sonst sind andere Paradigmen besser geeignet.

Untertypen und Vererbung[edit]

1. In welchen Formen (mindestens zwei) kann man durch das Ersetzbarkeitsprinzip Wiederverwendung erzielen?[edit]

  • Erweiterung, jedoch beibehalten der Schnittstelle
  • Ersetzbarkeit (Faktorisierung)
  • interne Code-Wiederverwendung

2. Wann ist ein struktureller Typ Untertyp eines anderen strukturellen Typs? Welche Regeln müssen dabei erfüllt sein? Welche zusätzliche Bedingungen gelten für nominale Typen bzw. in Java? (Hinweis: Häufige Prüfungsfrage!)[edit]

Allgemein gilt:

  • reflexiv (jeder ist sich selbst ein Untertyp)
  • transitiv (Untertyp von Untertyp ist Untertyp)
  • antisymmetrisch (wenn wechselseitige Untertypbeziehung, dann Gleichheit)

Generell gilt:

  • Konstante in T hat auch Konstante in U
  • Variable in T hat Variable in U (deklarierter Typ ist gleich)
  • Methode in T hat Methode in U (Ergebnistypen kovariant, gleiche Parameteranzahl, *Eingangsparameter kontravariant [in Java bedeutet das sonst überladen])
Kovarianz
Untertyp oder gleich des deklarierten Typs
Invarianz
gleicher Typ
Kontravarianz
Obertyp oder gleich des deklarierten Typs

3. Sind die in Punkt 2 angeschnittenen Bedingungen (sowie das, was Compiler prüfen können) hinreichend, damit das Ersetzbarkeitsprinzip erfüllt ist? Wenn nicht, was muss noch beachtet werden?[edit]

Ja, wenn das Verhalten nicht berücksichtigt wird (vgl. Zusicherungen). Sonst Nein.

4. Was bedeutet Ko-, Kontra- und Invarianz, und für welche Typen in einer Klasse trifft welcher dieser Begriffe zu? (Hinweis: Häufige Prüfungsfrage!)[edit]

5. Was sind binäre Methoden, und welche Schwierigkeiten verursachen sie hinsichtlich der Ersetzbarkeit?[edit]

Eine Methode, bei der ein formaler Parametertyp stets gleich der Klase ist, in der die Methode definiert ist, heißt *binär*.

> **Faustregel**: Kovariante Eingangsparametertypen und binäre Methoden widersprechen dem Ersetzbarkeitsprinzip. Es ist sinnlos, in solchen Fällen Ersetzbarkeit anzustreben.

(Die Eigenschaft binär bezieht sich darauf, dass der Name der Klasse in der Methode mindestens zweimal vorkommt – einmal als Typ von this und mindestens einmal als Typ eines formalen Parameters.)

6. Wie soll man Typen formaler Parameter wählen um gute Wartbarkeit zu erzielen?[edit]

> **Faustregel**: Man soll Parametertypen vorausschauend und möglichst allgemein wählen.

7. Warum ist dynamisches Binden gegenüber switch- oder geschachtelten if-Anweisungen zu bevorzugen?[edit]

8. Dient dynamisches Binden der Ersetzbarkeit und Wartbarkeit?[edit]

Durch dynamisches Binden können Optionen (Unterklassen) einfach hinzugefügt/entfernt werden, ohne die Struktur der anderen Klassen zu ändern.

9. Welche Arten von Zusicherungen werden unterschieden, und wer ist für die Einhaltung verantwortlich? (Hinweis: Häufige Prüfungsfrage!)[edit]

  • Vorbedingungen (@param,“Welche Eigenschaften sollen die Eingangsparameter haben?“)
  • Nachbedingungen (@result, „Was sagt das Ergebnis aus?“)
  • Invarianten (Gelten für alle Methoden, Zuständigkeit des Servers)
  • History-Constraint: schränken die Entwicklung von Objekten im Laufe der Zeit ein.
    • Server-kontrolliert: wie Invarianten. Z.B. ganzzahlige Zähler kann im Laufe der Zeit nur größer werden.
    • Client-kontrolliert: Reihenfolge der Methodenaufrufe einschränken. Z.B. Methode "Initialize" kann in jedem Objekt nur einmal aufgerufen werden.

Grundsätzlich ist der Programmierer für die Einhaltung der Zusicherungen verantwortlich. Hinweis: In Java sind Zusicherungen nur durch Kommentare auszudrücken.

10. Wie müssen sich Zusicherungen in Unter- und Obertypen zueinander verhalten, damit das Ersetzbarkeitsprinzip erfüllt ist? Warum? (Hinweis: Häufige Prüfungsfrage!)[edit]

→ Vorbedingungen kovariant → Nachbedinungen kontravariant

Zusicherungen des Obertyps müssen auch für den Untertypen gelten.

11. Warum sollen Signaturen und Typen stabil bleiben? Wo ist Stabilität besonders wichtig?[edit]

Bewahrung der (Abwärts-)Kompatibilität. Vor allem an der „Wurzel“ von Klassenhierarchien wichtig (allgemeine Typen). Gilt auch für Zusicherungen.

12. Was ist im Zusammenhang mit allgemein zugänglichen (= möglicherweise nicht nur innerhalb des Objekts geschriebenen) Variablen und Invarianten zu beachten?[edit]

Sie müssen in Zusicherungen bedacht werden.

13. Wie genau sollen Zusicherungen spezifiziert sein?[edit]

Als zum Typ (=Name+Schnittstelle+Zusicherungen) gehörend. Aber keine unnötigen Details.

14. Wozu dienen abstrakte Klassen und abstrakte Methoden? Wo und wie soll man abstrakte Klassen einsetzen?[edit]

Von abstrakten Klassen können keine Instanzen erzeugt werden, abstrakte Methoden müssen in Unterklassen implementiert werden. Hauptvorteil zum Interface ist die Code-Wiederverwendung. (ermöglichen auch Dinge wie das Pattern „Template-Method“)

15. Ist Vererbung das gleiche wie das Ersetzbarkeitsprinzip? Wenn Nein, wo liegen die Unterschiede?[edit]

Nein, Vererbung = Erweitern und Überschreiben Ersetzbarkeitsprinzip = Das Auftreten eines Elements kann durch ein anderes ersetzt werden

Eine Vererbungshierarchie garantiert allerdings in Java auch, dass das Ersetzbarkeitsprinzip erfüllt ist.

16. Worauf kommt es zur Erzielung von Codewiederverwendung eher an, auf Vererbung oder Ersetzbarkeit? Warum?[edit]

Die Wiederverwendung durch das Ersetzbarkeitsprinzip (bestehen expliziter Untertypbeziehungen) ist wesentlich wichtiger als die Wiederverwendbarkeit von Code durch Vererbung (Allerdings kann nur durch Vererbung Code direkt vererbt werden).

17. Was bedeuten folgende Begriffe in Java?[edit]

  • Objektvariable, Klassenvariable, statische Methode
  • Static-Initializer
  • geschachtelte und innere Klasse
  • final Klasse und final Methode
  • Paket, Class-Path, import-Anweisung

18. Wo gibt es in Java Mehrfachvererbung, wo Einfachvererbung?[edit]

Mehrfachvererbung mittels Interfaces, keine echte Mehrfachvererbung.

19. Welche Arten von import-Deklarationen kann man in Java unterscheiden? Wozu dienen sie?[edit]

  • import Classname; // ganze Klasse
  • import paket.*; // alle in diesem Ordner
  • import Datei; // diesen Pfad bis zu diesem Punkt importieren

20. Wozu benötigt man eine package-Anweisung?[edit]

21. Welche Möglichkeiten zur Spezifikation der Sichtbarkeit gibt es in Java, und wann soll man welche Möglichkeit wählen?[edit]

  • public – überall sichtbar, vererbbar
  • protected – in anderem Paket nicht sichtbar, aber vererbbar
  • default – nur im momentanen Paket sichtbar, vererbbar
  • private – nur in dieser Klasse

22. Wodurch unterscheiden sich Interfaces in Java von abstrakten Klassen? Wann soll man Interfaces verwenden? Wann sind abstrakte Klassen besser geeignet?[edit]

Interfaces (abstrakte Klassen zur Mehrfachvererbung, keine konkreten Implementierungen) haben Einschränkungen. Sie enthalten keinen Code, Zusicherungen sind essential für die Wahrung ihrer Integrität (nur abstrakte Methoden).

Abstrakte Klassen sind konkret, haben Code-Vererbung. Sollten verwendet werden wenn genau dies nötig ist, ansonsten sind Interfaces (Untertypbeziehungen) immer besser und wichtiger.

Generizität und Ad-hoc-Polymorphismus[edit]

1. Was ist Generizität? Wozu verwendet man Generizität?[edit]

Generische Klassen, Typen und Routinen (Methoden) erhalten Typparameter die für Typen eingesetzt werden können. Damit ist Generizität eine weitere Form des universellen Polymorphismus, die Wiederverwendung unterstützen kann.

Zweck: Wartbarkeit, Sicherheit, Wiederverwendung, Lesbarkeit

2. Was ist gebundene Generizität? Was kann man mit Schranken auf Typparametern machen, das ohne Schranken nicht geht?[edit]

Wenn zusätzliche Information über Typparameter nötig ist, benötigt man Schranken. Der Typparameter erweitert eine Schrankenklasse (Klasse <Typparameter extends Class>), kann als Typ der Schranke bei Zugriffen verwendet werden.

3. In welchen Fällen soll man Generizität einsetzen, in welchen nicht?[edit]

Pro
  • Wartbarkeit
  • Typsicherheit
  • Gleich strukturierte Klassen/Routinen (z.B. Containerklassen, Libraries)
  • leichtere Code-Änderungen
Kontra
  • kann Untertypbeziehungen nicht ersetzen
  • wenn keine Notwendigkeit besteht

4. Was bedeutet statische Typsicherheit in Zusammenhang mit Generizität, dynamischen Typabfragen und Typumwandlungen?[edit]

Der Compiler garantiert dass in Instanzen vom Typ <String> auch nur Strings eingefügt werden / enthalten sind. Typinferenz: Vorgang zur Berechnung der Typen.


5. Was sind (gebundene) Wildcards als Typen in Java? Wozu kann man sie verwenden?[edit]

Einsatz als Typparameter bzw. Schranken in Methoden (<? extends/super Class>).

  • Lesezugriffe fordern in solchen Methoden Kovarianz (from)
  • Schreibzugriffe fordern Kontravarianz (to)

6. Welche Arten von Generizität kann man hinsichtlich ihrer Übersetzung und ihrem Umgang mit Schranken unterscheiden? Welche Art wird in Java verwendet, und wie flexibel ist diese Lösung?[edit]

homogene Übersetzung
  • 1 generische Klasse bedeutet -> 1 nicht-generische Klasse
  • der Compiler garantiert Typsicherheit
  • wird in Java verwendet
heterogene Übersetzung
  • 1 generische Klasse -> n nicht-generische Klassen (für jede wird eine erzeugt)
  • bessere Laufzeiteffizienz

Beim Übersetzungsvorgang werden alle Ausdrücke in spitzen Klammern vernichtet und durch Type-Casting ersetzt.

7. Wie kann man Generizität simulieren? Worauf verzichtet man, wenn man Generizität nur simuliert?[edit]

Simulierte Generizität (Klonen der Klassen) führt zu mehrfachen Klassen und erschwert somit die Wartbarkeit.

8. Was wird bei der heterogenen bzw. homogenen Übersetzung von Generizität genau gemacht?[edit]

Die generischen Klassen werden vom Compiler umgewandelt in normale Klassen, welche Type Casting verwenden (homogen) oder für alle relevanten Untertypen erzeugt werden (heterogen).

9. Was muss der Java-Compiler überprüfen um sicher zu sein, dass durch Generizität keine Laufzeitfehler entstehen?[edit]

10. Welche Möglichkeiten für dynamische Typabfragen gibt es in Java, und wie funktionieren sie genau?[edit]

  • getClass() – Klasse eines Objekts als Ergebnis
  • instanceof-Operator – ist das Objekt links eines Instanz des Objekts rechts?

11. Was wird bei einer Typumwandlung in Java umgewandelt – der deklarierte, dynamische oder statische Typ? Warum?[edit]

Der deklarierte Typ wird umgewandelt in den gerade benötigten Typ im Programm (falls möglich). Compiler kennt nur den deklarierten Typ bzw. legt den statischen Typ fest, aber nicht den echten (dynamischen) Typ.

12. Welche Gefahren bestehen bei Typumwandlungen?[edit]

Class Cast Exceptions

  • die statische Typ-Überprüfung durch den Compiler wird übergangen
  • schlechte Wartbarkeit beim Einsatz vieler Typumwandlungen

13. Wie kann man dynamische Typabfragen und Typumwandlungen vermeiden? In welchen Fällen kann das schwierig sein?[edit]

Dynamisches Binden.

Schwierigkeiten:

  • bei sehr allgemeinen Typen (sollte vermieden werden)
  • Erweiterungen sind nicht erlaubt
  • wichtige private Methoden
  • sehr viele Untertypen werden benötigt

14. Welche Arten von Typumwandlungen sind sicher? Warum?[edit]

  • Typumwandlungen auf primitive Datentypen sind sicher (haben anderen Zweck)
  • Umwandlungen in den Obertyp
  • nach dynamischen Typ-Abfragen („else-Zweig“ bedenken)
  • wenn Programmierer die Verwendung genau geprüft hat

Weil dann nichts schiefgehen kann.

15. Was sind kovariante Probleme und binäre Methoden? Wie kann man mit ihnen umgehen oder sie vermeiden?[edit]

Kovariante Probleme: Treten auf wenn kovariante Eingangsparametertypen erwünscht sind. Das verletzt das Ersetzbarkeitsprinzip und sollte somit vermieden werden. Binäre Methoden: Empfangen einen Parameter der Klasse, der gleich der Klasse ist, was bei Vererbung zum Verhängnis wird.

→ keine gefährlichen Erweiterungen machen, lieber refaktorisieren

16. Wie unterscheidet sich Überschreiben von Überladen, und was sind Multimethoden?[edit]

Überschreiben
Methode in Unterklasse überschreibt Methode in Oberklasse, sie wird also verwendet, egal welcher Typ deklariert ist
Überladen
Methode in Unterklasse koexisitiert zu Methode in Oberklasse (tritt bei Java immer auf wenn: Eingangsparameter nicht invariant, Ausgangsparameter nicht kovariant)
Multimethoden
Methoden sind zwar koexistent, jedoch ist der dynamische Typ entscheidend

Bei überladenen Methoden entscheidet stets der deklarierte Typ über das Verhalten, was unerwünschtes Verhalten hervorruft.

17. Wie kann man Multimethoden simulieren? Welche Probleme können dabei auftreten?[edit]

Über mehrfaches dynamisches Binden. Es wird jedoch eine hohe Anzahl an Methoden benötigt.

18. Was ist das Visitor-Entwurfsmuster?[edit]

Über mehrfaches dynamisches Binden werden Multi-Methoden simuliert.

Es gibt Visitorklassen (vgl. Futter) und Elementklassen (vgl. Tier).

Durch die Methode in der bestimmten Klasse, wird die richtige Methode in der korrespondierenden Klasse korrekt aufgerufen.

19. Wodurch ist Überladen problematisch, und in welchen Fällen ergeben sich kaum Probleme?[edit]

Überladen ist dann problematisch, wenn die Namen gleich sind und zwischen den Parametern bei gleicher Typ-Anzahl Untertypbeziehungen bestehen. Das sollte vermieden werden.

Kreuz und quer[edit]

1. Wie werden Ausnahmebehandlungen in Java unterstützt?[edit]

Ausnahmen sind in Java gewöhnliche Objekte, die über spezielle Mechanismen als Ausnahmen verwendet werden. Alle Instanzen von Throwable sind dafür verwendbar. Praktisch verwendet man nur Instanzen der Unterklassen von Error und Exception, zwei Unterklassen von Throwable. Unterklassen von Error werden hauptsächlich für vordefinierte, schwerwiegende Ausnahmen des Java-Laufzeitsystems verwendet und deuten auf echte Fehler hin, die während der Programmausführung entdeckt wurden. Es ist praktisch kaum möglich, solche Ausnahmen abzufangen; ihr Auftreten führt fast immer zur Programmbeendigung.

2. Wie sind Ausnahmen in Untertypbeziehungen zu berücksichtigen?[edit]

Exceptions die auftreten können werden im Methodenkopf hinter dem Stichwort throws aufgelistet. Sei U ein Untertyp von T. In U darf keine Exceptions werfen, die in T nicht definiert sind.

3. Wozu kann man Ausnahmen verwenden? Wozu soll man sie verwenden, wozu nicht?[edit]

Dafür:

  • Unvorhergesehene Programmabbrüche
  • Kontrolliertes Wiederaufsetzen

Dafür nicht:

  • Ausstieg aus Sprachkonstrukten
  • Rückgabe alternativer Ergebniswerte

Generell sind Ausnahmen sparsam und wirklich nur in Ausnahmesituationen einzusetzen.

4. Durch welche Sprachkonzepte unterstützt Java die nebenläufige Programmierung? Wozu dienen diese Sprachkonzepte?[edit]

Java unterstützt nebenläufige Programmierung durch die Verwendung mehrerer Threads. Threads dienen zum parallelen Bearbeiten von Ressourcen.

5. Wozu brauchen wir Synchronisation? Welche Granularität sollen wir dafür wählen?[edit]

ei der Verwendung mehrerer Threads kann es wenn diese unkontrolliert auf Ressourcen zugreifen zu Inkonsistenzen, unerwarteten Folgen kommen,da nicht alle Threads gleichmäßig arbeiten. Eine gewisse Ressource (oder Methode) kann synchronisiert werden, damit immer nur ein Thread Zugriff darauf hat. Es ist die feinst-mögliche Granularität (Körnung) zu wählen, da Synchronisierung teuer bezüglich Laufzeit ist, da die anderen Transaktionen auf die momentan laufende warten müssen.

6. Zu welchen Problemen kann Synchronisation führen, und was kann man dagegen tun?[edit]

Deadlocks
Zyklische Abhängigkeiten zwischen mehreren Threads
(Thread A wartet auf Thread B und B wiederum wartet auf A)
Lifelocks
Alle arbeiten, aber es geschieht nichts!

7. Wozu dienen Annotationen? Wann setzt man sie sinnvoll ein?[edit]

8. Wie lange können Annotationen leben? Wofür ist welche Lebensdauer sinnvoll?[edit]

9. Wie kann man eigene Annotationen deklarieren? Welche Gemeinsamkeiten und Unterschiede zu Interfaces bestehen?[edit]

10. Wie kann man zur Laufzeit auf Annotationen zugreifen?[edit]

11. Was ist aspektorientierte Programmierung? Wann setze ich sie sinnvoll ein?[edit]

12. Was bedeutet Separation-of-Concerns?[edit]

13. Was sind Core-Concerns, was Cross-Cutting-Concerns?[edit]

14. Was sind Join-Points, Pointcuts, Advices und Aspekte, und wozu braucht man sie?[edit]

15. An welchen Programmpunkten können sich Join-Points befinden?[edit]

Software-Entwurfsmuster[edit]

1. Erklären Sie folgende Entwurfsmuster und beschreiben Sie jeweils Anwendungsgebiet, Struktur, Eigenschaften und wichtige Details der Implementierung unter Verwendung vorgegebener Namen:[edit]

  • Decorator
  • Factory-Method
  • Iterator
  • Prototype
  • Proxy
  • Singleton
  • Template-Method
  • Visitor

2. Welche Arten von Iteratoren gibt es, und wofür sind sie geeignet?[edit]

Interne Iteratoren
Selbstkontrolle (leichterer Umgang)
Externe Iteratoren
vom Anwender benutzt (schlecht für komplexe Beziehungen und schwieriger zu steuern, aber flexibler)

3. Wie wirkt sich die Verwendung eines Iterators auf die Schnittstelle des entsprechenden Aggregats aus?[edit]

Sie wird komplexer, da ein Iterator benötigt wird der gesteuert werden muss. Die interne Funktionalität des Aggregats wird versteckt.

4. Inwiefern können geschachtelte Klassen bei der Implementierung von Iteratoren hilfreich sein?[edit]

Ein interner Iterator kann auf alle Variablen/Methoden der Oberklasse zugreifen, wodurch weniger Nachrichten nötig sind.

5. Was ist ein robuster Iterator? Wozu braucht man Robustheit?[edit]

Ein Iterator der nicht kaputt gehen kann, wenn sich das Aggregat nach seiner Erzeugung verändert (durch Kopie des Aggregats oder gute Implementierung).

6. Wird die Anzahl der benötigten Klassen im System bei Verwendung von Factory-Method, Prototype, Decorator und Proxy (gegenüber einem System, das keine Entwurfsmuster verwendet) eher erhöht, vermindert oder bleibt sie unverändert?[edit]

  • Factory Method: Erhöhung der Klassen
  • Prototype: Wird niedriger
  • Decorator: Steigt
  • Proxy: Steigt (leicht)

7. Wird die Anzahl der benötigten Objekte im System bei Verwendung von Factory-Method, Prototype, Decorator und Proxy (gegenüber einem System, das keine Entwurfsmuster verwendet) eher erhöht, vermindert oder bleibt sie unverändert?[edit]

  • Factory Method: Bleibt gleich
  • Prototype: Bleibt gleich / steigt
  • Decorator: Steigt
  • Proxy: Bleibt gleich (Objekterzeugung nicht nötig) oder steigt

8. Vergleichen Sie Factory-Method mit Prototype. Wann stellt welches Entwurfsmuster die bessere Lösung dar? Warum?[edit]

FM: Delegiert Erzeugung an Unterklassen, mühsam die Struktur zu erweitern

PR: Erzeugt Kopien von deklarierten Typen, mühsam die neu erzeugten Typen zu verwalten

9. Wo liegen die Probleme in der Implementierung eines so einfachen Entwurfsmusters wie Singleton?[edit]

Entweder der Obertyp kennt alle Untertypen, oder die Untertypen müssen alle instance() implementieren.

10. Welche Unterschiede und Ähnlichkeiten gibt es zwischen Decorator und Proxy?[edit]

Ein Proxy kann dieselbe Struktur wie ein Decorator haben. Aber Proxies dienen einem ganz anderen Zweck als Decorators: Ein Decorator erweitert ein Objekt um zusätzliche Verantwortlichkeiten, während ein Proxy den Zugriff auf das Objekt kontrolliert. Damit haben diese Entwurfsmuster auch gänzlich unterschiedliche Eigenschaften.

11. Welche Probleme kann es beim Erzeugen von Kopien im Prototype geben? Was unterscheidet flache Kopien von tiefen?[edit]

Flache Kopie → alle Referenz-Variablen sind identisch

Tiefe Kopie → alles wird geklont (manchmal schwierig, problematische Zyklen)

12. Für welche Arten von Problemen ist Decorator gut geeignet, für welche weniger? (Oberfläche versus Inhalt)[edit]

Gut um das Erscheinungsbild von Objekten zu verändern, schlecht für inhaltliche Änderungen.

13. Kann man mehrere Decorators bzw. Proxies hintereinander verketten? Wozu kann so etwas gut sein?[edit]

Ja. Bei Decorators können auf diese Art und Weise z.B. umfangreiche GUIs gebildet werden. Bei Proxies gibt es beliebige Möglichkeiten, wie z.B. das Kapseln mehrerer Funktionalitäten.

14. Was unterscheidet Hooks von abstrakten Methoden?[edit]

"hooks" werden benutzt um definierte Teile eines Algorithmus zur Veränderung in Unterklassen freizugeben. Einen Teil des Codes enthalten sie selbst. Abstrakte Methoden hingegen erhalten keinen Code, sie werden lediglich über Zusicherungen implementiert.