• Shuffle
    Toggle On
    Toggle Off
  • Alphabetize
    Toggle On
    Toggle Off
  • Front First
    Toggle On
    Toggle Off
  • Both Sides
    Toggle On
    Toggle Off
  • Read
    Toggle On
    Toggle Off
Reading...
Front

Card Range To Study

through

image

Play button

image

Play button

image

Progress

1/40

Click to flip

Use LEFT and RIGHT arrow keys to navigate between flashcards;

Use UP and DOWN arrow keys to flip the card;

H to show hint;

A reads text to speech;

40 Cards in this Set

  • Front
  • Back

Warum kann Smalltalk nichts über mathematische Operatorpräferenzen wissen?

#+ und #* und andere Operatoren sind in Smalltalk binäre Nachrichtenselektoren. Der Compiler kann nicht davon ausgehen, dass #+ die Bdeutung von Addition und #* die Bedeutung von Multiplikation hat. Insofern kann er auch keine Präzendenzen annehmen.

Welche Objekte verstehen die Nachricht #new?

Alle Klassen und alle Metaklassen verstehen die Nachricht #new und antworten in der Regel mit einer neuen Instanz ihrer Klasse.

Wo ist #new das erste Mal implementiert?

#new ist in Behaviour, einer Superklasse von class, implementiert.

Woran erkennt man in Smalltalk Methoden, in denen das Prinzip von Generalisierung und Spezialisierung außer Acht gelassen wurde?

gelöschte Methoden, die nur shouldNotImplement enthalten

Wie findet man in Smalltalk gelöschte Methoden?

Man sucht nach Sendern von #shouldNotImplement

Was sind Instanzvariablen?

- Jedem Objekt kann eine Menge von lokalen Variablen zugeordnet werden, die Instanz-
variablen.


- Die Instanzvariablen eines Objekts sind in gewisser Weise in seinem Besitz: In
SMALLTALK sind sie für andere Objekte nicht sichtbar und damit auch nicht zugreifbar.


- Die Sichtbarkeit ist also auf das jeweils besitzende Objekt eingeschränkt.

Wie gelangen in SMALLTALK Objekte in den Besitz von Instanzvariablen?

- Man verbindet die Instanzvariablen mit Klassen und vereinbart, dass alle mit einer
Klasse verbundenen Eigenschaften und Verhaltensspezikationen nicht die Klasse in ihrer
Gesamtheit, sondern die einzelnen Objekte, die zu der Klasse gehören, beschreiben


-

Wie kann man die Komposition in objektorientierten Programmiersprachen umsetzen?

- Die meisten (objektorientierten) Programmiersprachen bieten leider überhaupt kein Sprachkonstrukt an, das speziell für die Teil-Ganzes-Beziehung gedacht wäre.


- Gleichwohl kann man die Unterscheidung zwischen Instanzvariablen mit Referenz- und Wertsemantik, falls vorhanden, dazu nutzen, um zumindest eine spezielle Form derTeil-Ganzes-Beziehung abzubilden:


- Da bei Wertsemantik mit der Entfernung eines Objekts aus dem Speicher auch alle Objekte, die als Werte seiner Instanzvariablen dienen, aus dem Speicher entfernt werden, kann man hier tatsächlich von der Umsetzung einer bestimmten Form von Teil-Ganzes-Beziehung sprechen, nämlich einer solchen, bei der die Existenz der Teile von der
Existenz des Ganzen abhängt

Welche beiden Formen von Ausdrücken sind wichtige Ausdrucksformen für die objekt-
orientierte Programmierung? Warum sind sie wichtig?

- Die Zuweisungen und die Nachrichtenausdrücke sind wichtig.


- Zuweisungen bewirken als einzige Ausdrücke den Zustandswechsel von Objekten.


- Die Nachrichtenausdrücke sind wichtig, weil ja das Weltbild der objektorientierten Programmierung umgesetzt werden muss:


- Es gibt Objekte, die einander Nachrichten schicken und die in Reaktion auf diese Nachrichten ihren Zustand ändern.


- Nachrichtenausdrücke werden ausgewertet, indem die Nachricht an das Empfängerob jekt mit den Parametern gesendet und das Empfängerobjekt als Ergebnis der Nachricht
ein Objekt zurückliefert

Was beschreiben Methodendenitionen?

Methodendenitionen beschreiben, was ein Objekt in Reaktion auf den Erhalt einer
entsprechenden Nachricht tun soll.

Wie funktioniert das Versenden von Nachrichten in SMALLTALK?

- Aus Effzienzgründen wird in SMALLTALK ein Nachrichtenausdruck in einen Methodenaufruf übersetzt.


- Wann immer ein Objekt eine Nachricht an ein Empfängerobjekt verschickt, wechselt der Kontrollfluss damit zum Empfängerobjekt, genauer zu der Methode des Empfängerobjekts, das zur Reaktion auf die Nachricht vorgesehen ist.


- Nach der Abarbeitung der Methode kehrt der Kontrolluss an das sendende Objekt (genauer: zu der Methode, aus der die Nachricht versandt wurde) zurück und setzt seine Arbeit dort fort.


- Bei der Rückkehr wird auch das Ergebnis der Methode, (eine Referenz auf) ein Objekt, geliefert, das dann an der Stelle des Nachrichtenausdrucks, der den Methodenaufruf bewirkt hat, eingesetzt wird.

Methodenaufrufe in der objektorientierten Programmierung werden oft mit Funktions-
aufrufen in der prozeduralen Programmierung verglichen. Was ist der kleine, aber feine
Unterschied zum gewöhnlichen Prozeduraufruf?

- Der Unterschied besteht in der Abhängigkeit vom Empfängerobjekt:


- Die Entscheidung, welche Methode in Reaktion auf einen Nachrichtenversand aufgerufen und abgearbeitet wird, hängt nicht von dem Nachrichtenselektor allein ab, sondern auch von dem Objekt, an das die Nachricht geschickt wird.


- Es ist nämlich durchaus üblich, dass verschiedene Objekte mit gleichen Methodensignaturen unterschiedliche Methodenimplementierungen verbinden; so implementieren beispielsweise Zahlen und Symbole die Methode printString
jeweils anders.


- Aus der Abhängigkeit des Methodenaufrufs vom Empfängerobjekt folgt, dass nicht immer schon zur Übersetzungszeit entschieden werden kann, welche Methodenimplementierung bei einem Methodenaufruf ausgewählt werden muss.


- Wenn nämlich das Empfängerobjekt durch eine Variable benannt oder von einem Ausdruck geliefert wird, kann die Zuordnung einer Methodendefinition zu einem Nachrichtenausdruck erst zum Zeitpunkt der Auswertung des Nachrichtenausdrucks und damit erst zur Laufzeit erfolgen
(dynamisches Binden).

Was unterscheidet die klassenbasierte von der prototypenbasierten Form der objektorientierten Programmierung?

- Es ist bei der klassenbasierten Form nicht vorgesehen, dass verschiedene Instanzen
einer Klasse über verschiedene Denitionen einer Methode (genauer: über verschiedene
Denitionen von zu der Nachricht passenden Methoden) verfügen.


- Die prototypenbasierte Form der Objektorientierung kann sehr viel exibler einzelne Objekte an ihren jeweiligen Zweck anpassen, z.B. indem sie eine Methodendefinition nur für ein einziges Objekt abzuändern erlaubt.


- Letzteres ist z.B. bei der Programmierung von
grafischen Bedienoberflächen, bei der das Drücken verschiedener Buttons jeweils verschiedene Ereignisse auslöst (Methoden aufruft), sehr praktisch

Warum ist es sinnvoll, dass zu jeder Klasse des SMALLTALK-Systems genau eine Metaklasse gehört?

- Die Programmierpraxis hat gezeigt, dass es günstig ist, wenn jede Klasse (als Instanz)
ihre eigenen Instanzvariablen und Methoden besitzt und wenn die Programmiererin diese
jeweils frei bestimmen kann, ohne dabei gleichzeitig an andere Klassen denken zu müssen.


- Um dies zu ermöglichen, muss aber jede Klasse Instanz einer eigenen Klasse sein, in der
diese Variablen und Methoden nur für sie angelegt werden können.


- Und genau das ist in
SMALLTALK der Fall.


- Zu jeder Klasse des SMALLTALK-Systems gehört nämlich genau eine Klasse, von der
erstere (und nur diese) eine Instanz ist. Diese zweite Klasse wird Metaklasse der ersten
genannt.

Was ist ein Konstruktor?

Ein Konstruktor ist eine Methode, die, auf einer Klasse aufgerufen, eine neue Instanz dieser Klasse zurückgibt (es handelt sich also aus Sicht der erzeugten Instanz um eine Klassenmethode)

Was sind Factory-Methoden? Warum ist es in SMALLTALK leicht möglich, diese zu implementieren?

- Eine Factory-Methode ist eine Methode, die wie ein Konstruktor eine neue Instanz
liefert, die aber die Klasse der Instanz von anderen Faktoren als nur der Klasse, zu der die
Methode gehört, abhängig macht.


- Zum Beispiel könnte eine Klasse Number eine (Klassen-)Methode fromString: vorsehen, die anhand eines zu analysierenden Strings entweder eine Instanz der Klasse Integer oder eine der Klasse Float zurückgibt.


- Da in SMALLTALK Konstruktoren ganz normale Klassenmethoden sind, sind sie an
keine besonderen Konventionen gebunden.


- Sie müssen also insbesondere nicht ein neues
Objekt genau der Klasse, der sie angehören, zurückgeben.


- Die Factory-Methoden sind dann solche Klassenmethoden.

Was sind Typen?

Typen sind abstrakte Spezifikationen, die zum einen den Wertebereich von Vari-
ablen einschränken und zum anderen das Protokoll (den Funktionsumfang) von
Objekten angeben

Was muss ein Typsystem überprüfen, um in einem Programm Freiheit von
semantischen Fehlern zu garantieren?

Ein Typsystem muss lediglich alle Wertzuweisungen in einem Programm über-
prüfen, um Freiheit von semantischen Fehlern zu garantieren. Dazu zählen aller-
dings auch die impliziten Zuweisungen bei Methodenaufrufen, die, auch wegen
des dynamischen Bindens, nicht immer alle offensichtlich sind.

Was versteht man unter dynamischer Typprüfung?

Bei der dynamischen Typprüfung prüft man zur Laufzeit vor einer Variablen-
zuweisung, ob der zuzuweisende Wert den von der Variable geforderten Typ
hat.

Führt SMALLTALK dynamische Typprüfung durch?

SMALLTALK führt keine dynamische Typprüfung durchführt, da Typfehler erst
im letztmöglichen Moment offenbar werden, nämlich wenn auf einer Variable
eine Methode aufgerufen werden soll, die für das Objekt, auf das die Variable
verweist, gar nicht definiert ist.

Was versteht man unter statischer Typprüfung? Was ist ein Nachteil der sta-
tischen Typprüfung?

Bei der statischen Typprüfung soll die Typkorrektheit zur Übersetzungszeit ge-
währleistet werden. Die Typprüfung ist Aufgabe des Compilers.
Nachteil der rein statischen Typprüfung ist, dass sie auch Programme zurück-
weist, die nützlich, sinnvoll und typkorrekt sind.

Was ist ein Subtyp?

- Ein Subtyp ist als ein Typ definiert, dessen Werte oder Objekte überall da auftauchen dürfen, wo ein Wert des Typs, von dem er ein Subtyp ist, verlangt wird.


- Subtyp steht dabei nicht für eine besondere Art von Typ, sondern vielmehr für eine Rolle in einer Beziehung zwischen zwei Typen, nämlich der Subtypenbeziehung.


- Die Gegenrolle heißt Supertyp.
- Ein Subtyp ist also mit seinem Supertyp per Definition zuweisungskompatibel.
- Es gilt die folgende Regel: „Wenn ein Typ Y ein Subtyp eines Typs X ist, dann
müssen alle Bedingungen, die für Objekte des Typs X erfüllt sind, auch für Objekte des Typs Y erfüllt sein.“

Wenn Loewe Subtyp von Katze ist, ist dann auch das Array Loewe[ ] Subtyp des Katzen-Array Katze[ ]? Was bedeutet das für die Typprüfung in Java?

- In Java ist das richtig: Man hat hier auf die statische Typprüfung zugunsten einer
dynamischen Typprüfung mit möglicher Meldung eines Laufzeitfehlers verzich-
tet.


- Dies tut man immer dann, wenn die statische Typprüfung Programme verhindert, die man gern schreiben möchte und die auch korrekt sein können, ohne dass dies jedoch vom Compiler garantiert werden könnte.


Beispiele dafür sind Programme, die Prozeduren verwenden, die auf einer Menge von Objekten durchgeführt werden können sollen, die aber nicht verlangen, dass die Elemente alle vom gleichen Typ sind, sondern statt dessen gestatten, dass auch Elemente
von Subtypen darunter vorkommen.

Eine Klassendefinition hält in der Regel auch als Typdefinition her. Warum ist das sinnvoll?

- Klassen dienen der Angabe von Implementierungen und damit als Container
von ausführbarem Code;


- Typen dienen der Formulierung von Invarianten, die für Variablenbelegungen gelten müssen und deren Verletzung auf einen (logischen oder semantischen) Programmierfehler hinweist.


- Da beide im Wesentlichen über die gleichen Elemente verfügen, lässt sich die Definition beider in einem Sprachkonstrukt zusammenfassen.

Wo manifestiert sich der Unterschied der beiden Konzepte Klasse und Typ?

- Der Unterschied der beiden Konzepte Klasse und Typ manifestiert sich auch darin, welche Rolle sie zur Laufzeit eines Programms spielen: - Typinformation beeinflusst die Ausführung eines laufenden Programms insofern, als sie ein Programm bei Verletzung einer Invariante abbrechen läßt (durch einen dynamischen
Typtest) und damit einem anderen, schwieriger zuordenbaren Fehler zuvorkommt.


- Klasseninformation beeinflusst die Ausführung des laufenden Programms insofern, als sie Grundlage des dynamischen Bindens ist und in einem Programm als Eigenschaft von Objekten abgefragt werden kann.

Zu welchem Zeitpunkt führt die Verwendung eines parametrisch definierten Typs zu einer Zuweisung an die Typvariable?

Die Verwendung eines parametrisch definierten Typs führt bereits zur Übersetzungszeit zu einer Zuweisung an die Typvariablen.

Warum benötigt man den einfachen parametrischen Polymorphismus? Erläutern Sie bitte die Problematik am Beispiel Collection.

- Zur Vermeidung einer Sicherheitslücke in der statischen Typprüfung:


- Collections sind das typische Beispiel für die Verwendung des parametrischen
Polymorphismus.


- Man könnte die Collections aber auch als Collections von Object definieren.


- Da in STRONGTALK alle Typen Subtypen von Object sind, kann man jedes beliebige Objekt in einer solchen Collection speichern.


- Wenn ein solches Objekt von einem Subtyp von Object ist, muss man eine Typumwandlung durchführen, wenn man spezielle Subtypeigenschaften dieses Objektes nut-
zen will.


- Die Zulässigkeit dieses Down cast ist aber davon abhängig, was wirklich in der Collection drinsteckt, und das kann der Compiler nicht (oder nur sehr aufwendig) feststellen.


- Die Lösung, die Inklusionspolymorphie bietet, beinhaltet also eine Sicherheitslücke in der statischen Typprüfung, die der parametrische
Polymorphismus behebt

Welche Unzulänglichkeiten hat der einfache parametrische Polymorphismus? Erläutern Sie bitte die Problematik am Beispiel Collection.

- Auch beim einfachen parametrischen Polymorphismus kann man nicht vollständig auf Typumwandlungen verzichten, weil eine Collection mit Elementtyp XYZ auch Objekte eines Subtyps von XYZ speichern kann.


- Zum anderen wird die erhöhte Typsicherheit bei der Verwendung von parametrisch definierten Typen mit einer geringeren Typsicherheit innerhalb der Typdefinition (bzw. Klassendefinition) selbst erkauft

Wie kann die Regel Wenn ein Typ Y ein Subtyp eines Typs X ist, dann müssen alle
Bedingungen, die für Objekte des Typs X erfüllt sind, auch für Objekte des Typs Y erfüllt
sein überprüft werden? Was kann der Compiler prüfen?

Liskov-Substitutionsprinzip:


1. Überschreibende Methoden in S erhalten das Verhalten der überschriebenen Methoden in T.


- Dazu gehört:
a) Kontravarianz der Argumenttypen der überschreibenden Methode
b) Kovarianz des Ergebnistyps der überschreibenden Methode
c) Kovarianz der Ausnahmen der überschreibenden Methode (die Typen der ge-
worfenen Exceptions sind entweder Subtypen von den Typen der Exceptions der überschriebenen Methode oder die Exceptions werden gar nicht geworfen; keinesfalls kommen Exceptions hinzu)
d) Vorbedingungen der überschriebenen Methode implizieren Vorbedingungen der
überschreibenden
e) Nachbedingungen der überschriebenen Methode werden von Nachbedingungen
der überschreibenden Methode impliziert
2. Die Invarianten von S implizieren die von T.
- Die Bedingungen 1. a) b) c) kann der Compiler prüfen.

Was unternimmt C#, um das Fragile-base-class-Problem zu vermeiden?

- In C# sind dynamisch zu bindende Methoden unbedingt als solche zu deklarieren, und
zwar mit dem Schlüsselwort virtual.


- Entsprechend muss eine überschreibende Methode mit dem Schlüsselwort override deklariert werden.


- Soll hingegen eine Methode gleicher
Signatur in einer Subklasse neu eingeführt (und nicht anstelle der, die sie überschreibt,
dynamisch gebunden) werden, dann ist dies durch Verwendung des Schlüsselworts new
bekanntzugeben.


- Dadurch markiert man alle Stellen im Programm, an denen das sog. Fragile-base-class-Problem auftreten kann.

Wie kann ein Objekt verbergen, welche Objekte es kennt?

Es kann dies über lokale Instanzvariablen tun.

Welchen Schutz bietet die mangelnde Sichtbarkeit von Variablen vor unerwünschtem
Zugriff auf Objekte?

- Aufgrund des Aliasing kann ein Objekt, dessen einer Name (beispielsweise aufgrund des Geheimnisprinzips) unsichtbar ist, über einen anderen zugreifbar sein, ohne dass der erste Name etwas dagegen machen könnte.


- Über lokale Instanzvariablen kann ein Objekt also verbergen, welche Objekte es kennt; es kann aber nicht verhindern, dass andere Objekte diese Objekte schon kennen und, ohne sein Wissen, manipulieren.


- Es ist somit wegen der etwaigen Existenz von Aliasen nicht möglich, dass ein Objekt seinen inneren Aufbau vor der Außenwelt abkapselt, es sein denn, es hat ganz spezielle Vorkehrungen dafür getroffen.

Die Unterscheidung von Wert- und Referenztypen einer Klasse hat in EIFFEL einen
starken konzeptuellen Hintergrund. Welchen?

- Die Unterscheidung von Wert- und Referenztypen einer Klasse unterstützt die Komposition und ihre Abgrenzung als eine besondere Beziehung zwischen Objekten, nämlich der, die das Enthaltensein von Objekten in anderen ausdrückt.


- Nun ist es in der Realität so, dass nicht alle Instanzen einer Klasse immer entweder Komponenten (also in anderen Objekten enthalten) oder freie Objekte (also nirgends enthalten) sind.


- EIFFEL wird dem gerecht, indem es erlaubt, von einer Klasse fallweise Komponentenobjekte (über expanded
Variablen) und freie Objekte (über normale Variablen) zu haben.

Wie funktionieren in EIFFEL Zuweisungen zwischen Variablen, die unterschiedliche
Semantik haben?

- Bei der Zuweisung zwischen zwei Variablen mit Wertsemantik wird der Wert der einen
Variable in die andere Variable kopiert.


- Bei der Zuweisung zwischen zwei Variablen mit Referenzsemantik wird lediglich der Zeiger kopiert


- Bei der Zuweisung einer Variable mit Referenzsemantik an eine Variable mit Wertsemantik reicht es jedoch nicht, einen Zeiger zu kopieren, denn die Zielvariable hat keinen Platz für einen Zeiger, sondern für die Attributwerte - statt dessen wird hier das Objekt, auf das der Zeiger verweist, kopiert


- Wenn eine Variable mit Wertsemantik an eine Variable mit Referenzsemantik zugewiesen
wird, wird ein Klon des Objekts erzeugt und eine Referenz auf diesen Klon übergeben.

Was sind Repräsentationsobjekte?

Dies sind Objekte, die die Implementierung eines Objektes ausmachen und die hinter der Schnittstelle des Objektes verborgen werden sollen.

Welchen Lösungsansatz gibt es für das Problem der mangelnden Kapselung?

- Man kann das Bestreben nach Kapselung als Ausdruck des Bestehens einer Teil-Ganzes-
Beziehung zwischen den Repräsentationsobjekten und dem Objekt, dessen Repräsentation sie ausmachen, verstehen.


- Die Teile sollen dabei dem Ganzen gehören in dem Sinne, dass sie nicht zugleich auch Teile anderer Objekte sein können, und darüber hinaus auch nicht von anderen Objekten referenziert werden können.


- Letzteres kann man auf einfache Weise
verhindern, wenn man aus den Objekten Wertobjekte macht und die verwendete Programmiersprache keine Zeiger auf Wertobjekte erlaubt.

Wie versucht C#, das Problem der mangelnden Kaspelung zu lösen?

In C# kann man die Klasse der Teil-Objekte per struct denieren.

Welche Lösung bietet EIFFEL für das Problem der mangelnden Kaspelung an?

- Zwar erlaubt EIFFEL, auf Wertobjekte Referenzen zu haben (und somit zumindest
theoretisch, dass ein Repräsentationsobjekt einen Alias besitzt), aber bei der Zuweisung
einer Referenzvariable an eine Wertvariable wird immer eine (aliasfreie) Kopie des referenzierten Objekts erzeugt und zugewiesen, so dass kein Alias in die Repräsentation hinein entstehen kann.


- Umgekehrt wird bei der Zuweisung eines Wertobjekts an eine Referenzvariable immer
eine Kopie des Wertobjekts erzeugt und die Referenz darauf angelegt.


- Es entsteht also faktisch kein Alias auf ein Wertobjekt, und als Wertobjekte angelegte
Repräsentationsobjekte sind aliasfrei.

Was ist ein Pluggable Block in Smalltalk?

- einem Objekt wird ein Block als Argument geschickt


- dieser Block beschreibt das Verhalten des Empfängerobjekts, das nicht im Empfängerobjekt selbst festgelegt wurde.

Wo liegt die Problematik des Friend-Konzeptes in Bezug auf die Kapselung?

- für eine Friendfunktion oder Friendklasse sind alle Member der jeweiligen Klasse zugreifbar


- man kann zwar nicht nur mit einer ganzen Klasse, sondern auch mit einzelnen Methoden befreundet sein, man kann aber nicht angeben, dass die jeweilige Klasse oder Memberfunktion ausschließlich Zugriff auf bestimmte private Member hat


- es ist also nicht möglich vor derartigen Freunden etwas zu verstecken


- dies verstößt gegen das Prinzip der Kapselung und macht für Freunde die gesamte Klasse mit all ihren Membern zur öffentlichen Schnittstelle