Grundlagen der Informatik I “Programmierung”

Grundlagen der Informatik I “Programmierung” Grundlagen der Informatik I “Programmierung”

22.08.2013 Aufrufe

Definition 3.8.5 (Konformität) Ein Datentyp B ist genau dann konform zu einem Datentyp A (“B conforms to A”), wenn eine der folgenden Bedingungen erfüllt ist. 1. A und B sind identisch, 2. A ist von der Form expanded B oder B ist von der Form expanded A, 3. A ist REAL oder DOUBLE und B ist INTEGER oder REAL, 4. A ist eine Klasse ohne generische Parameter und B ist eine Klasse, die A in der inherit-Klausel aufführt, 5. A ist von der Form G[A1, ..An] und B führt G[B1, ..Bn] in der inherit-Klausel auf, wobei G eine generische Klasse ist und jedes der Bi zu Ai konform ist, 6. B ist von der Form like anchor und der Typ von anchor ist konform zu A, 7. Es gibt einen Typen C mit der Eigenschaft, daß B konform ist zu C und C konform zu A. Eine ausführliche Diskussion von Konformität und weitere Verfeinerungen der Definition findet man in [Meyer, 1992, Kapitel 13]. Vererbung und Redefinition begünstigen einen Softwareentwicklungsstil, der sich vollkommen von den bisher üblichen Vorgehensweisen unterscheidet. Statt jedes Problem ganz von Neuem zu lösen, kann man auf Lösungen ähnlicher Probleme aufbauen, ihre Dienstleistungen erweitern und gegebenenfalls durch Redefinition für die spezielle Fragestellung optimieren. Diese Form der Wiederverwendung bestehender Softwaremodule ist hochgradig ökonomisch und bescheiden zugleich: sie erkennt die Leistungen anderer Softwareentwickler an, anstatt sie durch eine völlige Neuentwicklung zu ignorieren. Die Notwendigkeit, hierfür die Gemeinsamkeiten zwischen Gruppen verwandter Daten zu berücksichtigen, findet ebenfalls eine Antwort: in Netzwerken von Klassen, die durch Vererbung miteinander verbunden sind, können wir die logischen Beziehungen zwischen diesen Gruppen ausdrücken. Wiederverwendbarkeit wird dadurch gefördert, daß die Deklaration eines features soweit wie möglich nach oben verschoben wird, damit dieses feature in einer großen Anzahl von Nachkommen zur Verfügung steht. 3.8.4 Polymorphismus Wir haben gesehen, daß durch Vererbung die Wiederverwendbarkeit von Softwaremodulen erheblich gesteigert werden kann. Darüber hinaus hat Vererbung aber noch einen weiteren wichtigen Aspekt, nämlich Polymorphismus. Dieser Begriff bezeichnet im allgemeinen die Fähigkeit, verschiedene Formen anzunehmen. Im Rahmen einer typisierten Sprache wie Eiffel bedeutet dies, daß Größen eines Programmtextes zur Laufzeit auf Exemplare verschiedener Klassen verweisen dürfen. So ist zum Beispiel vom intuitiven Verständnis her jeder Arbeitnehmer auch eine Person – und nicht etwa etwas, was erst durch eine Konvertierung zu einer Person werden kann. Aufgrund des Vererbungskonzepts findet dieser intuitive Zusammenhang in Eiffel ein natürliches Gegenstück: eine Größe p vom Typ PERSON darf zur Laufzeit durchaus auf ein Arbeitnehmer- oder ein Universitätsangestellten-Objekt bezeichnen. Bei Programmiersprachen mit einem starren Typkonzept wäre hierfür eine explizite Konvertierung notwendig 26 . Polymorphismus ist in einer Sprache wie Eiffel leicht zu realisieren, da ja alle Größen eines Klassentyps in Wirklichkeit Verweise auf Objekte sind. Polymorphismus in Eiffel hat daher nichts zu tun mit Objekten, die ihre Form während der Laufzeit ändern, sondern bedeutet nur, daß eine gegebene Größe auf Objekte verschiedener Art verweisen kann. Durch Vererbung wird Polymorphismus also prinzipiell ermöglicht, aber gleichzeitig auch auf ein sinnvolles Maß begrenzt: eine Größe a vom Typ ARBEITNEHMER darf nicht ein einfaches Personenobjekt 26 Eine einzige Ausnahme bilden Zahlen der Typen INTEGER und REAL, die in fast allen Sprachen automatisch ineinander umgewandelt werden, ohne daß es hierzu eines gesonderten Konvertierungsbefehls bedarf.

ezeichnen, denn nicht jede Person ist auch ein Arbeitnehmer. Vererbung ist also ein Kontrollmechanismus für Polymorphismus, der einerseits eine vollständige Klassifizierung aller Objekte ermöglicht und dennoch eine gewisse – der Realität entsprechende Freiheit – zuläßt. Vererbung liefert auch eine Lösung für die am Ende des Abschnitts 3.6.2 angesprochene Problematik, daß Listen, die aus Elementen verschiedener Klassen bestehen, bisher nicht möglich waren. Ohne Vererbung wäre es ausgesprochen schwierig, in einem Bibliothekenverwaltungsystem die unterschiedlichen Arten von Benutzern – Entleiher, Universitätsangestellte, Professoren und Mitarbeiter der Bibliothek – in einer gemeinsamen Liste zu verwalten. Diese Form von Polymorphismus kann nun sehr leicht realisiert werden: man versucht einfach, eine gemeinsame Oberklasse BENUTZER zu definieren, deren Erben die Klassen ENTLEIHER, UNI-ANGESTELLTE, PROFESSOR und MITARBEITER sind, und deklariert die gewünschte Liste als benutzerliste:LIST[BENUTZER]. Die in benutzerliste eingetragenen Verweise dürfen dann, wie in Abbildung 3.33 gezeigt, auf Exemplare aller Erbenklassen von BENUTZER zeigen. Professorenobjekt Studentenobjekt Mitarbeiterobjekt Professorenobjekt ◗❦ ◗ ◗ ◗ ◗ ◗ ◗ ◗ ◗ benutzerliste ◗ ✲ ❆❑ ❆ ❆ ❆ ❆ ❆ ❆ ✁ ✁✁✁✁✁✁✕ Abbildung 3.33: Eine polymorphe Liste ✑✸ ✑✑✑✑✑✑✑✑ ✑ Ein unbeschränkter Polymorphismus ist in Eiffel jedoch nicht möglich, da dies dem Gedanken der Klassifizierung von Objekten in Gruppen mit gemeinsamen Merkmalen widersprechen würde. Eine Zuweisung p:=a ist deshalb durchaus möglich, wenn p vom Typ PERSON und a vom Typ ARBEITNEHMER ist, nicht jedoch a:=p. Im ersten Fall ist nämlich immer sichergestellt, daß p auf ein Objekt der Klasse PERSON bzw. ihrer Nachkommen zeigt, während im zweiten Fall a nach der Zuweisung durchaus auf ein Objekt zeigen könnte, welches die in der Klasse ARBEITNEHMER vereinbarten Merkmale überhaupt nicht kennt 27 . Hinter dieser Einschränkung steht eine weitere grundsätzliche Regel des Typsystems von Eiffel. Entwurfsprinzip 3.8.6 (Regel der Typverträglichkeit) Eine Zuweisung der Form x:=y, wobei x vom Typ A und y vom Typ B ist, ist nur dann zulässig, wenn B konform zu A ist. Gleiches gilt für den Aufruf einer Routine mit formalem Parameter x und aktuellem Parameter y, wobei x vom Typ A und y vom Typ B ist. Der Aufruf ist nur dann zulässig, wenn B konform zu A ist. 27 Die Zuweisung a:=p ist selbst dann verboten, wenn unmittelbar zuvor der Befehl p:=a ausgeführt wurde und p somit tatsächlich auf ein Objekt der Klasse ARBEITNEHMER verweist. Will man einen Verweis an ein Objekt binden, so muß sichergestellt sein, daß dessen Typ mit dem des Verweises verträglich ist. Jede andere Regelung würde nur einen schlechten Programmierstil fördern. Wenn von vorneherein beabsichtigt ist, daß p nur ein Arbeitnehmerobjekt enthalten soll, dann sollte man p entsprechend deklarieren.

Definition 3.8.5 (Konformität)<br />

Ein Datentyp B ist genau dann konform zu einem Datentyp A (“B conforms to A”), wenn eine <strong>der</strong> folgenden<br />

Bedingungen erfüllt ist.<br />

1. A und B sind identisch,<br />

2. A ist von <strong>der</strong> Form expanded B o<strong>der</strong> B ist von <strong>der</strong> Form expanded A,<br />

3. A ist REAL o<strong>der</strong> DOUBLE und B ist INTEGER o<strong>der</strong> REAL,<br />

4. A ist eine Klasse ohne generische Parameter und B ist eine Klasse, die A in <strong>der</strong> inherit-Klausel aufführt,<br />

5. A ist von <strong>der</strong> Form G[A1, ..An] und B führt G[B1, ..Bn] in <strong>der</strong> inherit-Klausel auf, wobei G eine generische<br />

Klasse ist und jedes <strong>der</strong> Bi zu Ai konform ist,<br />

6. B ist von <strong>der</strong> Form like anchor und <strong>der</strong> Typ von anchor ist konform zu A,<br />

7. Es gibt einen Typen C mit <strong>der</strong> Eigenschaft, daß B konform ist zu C und C konform zu A.<br />

Eine ausführliche Diskussion von Konformität und weitere Verfeinerungen <strong>der</strong> Definition findet man in<br />

[Meyer, 1992, Kapitel 13].<br />

Vererbung und Redefinition begünstigen einen Softwareentwicklungsstil, <strong>der</strong> sich vollkommen von den bisher<br />

üblichen Vorgehensweisen unterscheidet. Statt jedes Problem ganz von Neuem zu lösen, kann man auf Lösungen<br />

ähnlicher Probleme aufbauen, ihre Dienstleistungen erweitern und gegebenenfalls durch Redefinition für<br />

die spezielle Fragestellung optimieren. Diese Form <strong>der</strong> Wie<strong>der</strong>verwendung bestehen<strong>der</strong> Softwaremodule ist<br />

hochgradig ökonomisch und bescheiden zugleich: sie erkennt die Leistungen an<strong>der</strong>er Softwareentwickler an,<br />

anstatt sie durch eine völlige Neuentwicklung zu ignorieren.<br />

Die Notwendigkeit, hierfür die Gemeinsamkeiten zwischen Gruppen verwandter Daten zu berücksichtigen,<br />

findet ebenfalls eine Antwort: in Netzwerken von Klassen, die durch Vererbung miteinan<strong>der</strong> verbunden sind,<br />

können wir die logischen Beziehungen zwischen diesen Gruppen ausdrücken. Wie<strong>der</strong>verwendbarkeit wird dadurch<br />

geför<strong>der</strong>t, daß die Deklaration eines features soweit wie möglich nach oben verschoben wird, damit<br />

dieses feature in einer großen Anzahl von Nachkommen zur Verfügung steht.<br />

3.8.4 Polymorphismus<br />

Wir haben gesehen, daß durch Vererbung die Wie<strong>der</strong>verwendbarkeit von Softwaremodulen erheblich gesteigert<br />

werden kann. Darüber hinaus hat Vererbung aber noch einen weiteren wichtigen Aspekt, nämlich<br />

Polymorphismus. Dieser Begriff bezeichnet im allgemeinen die Fähigkeit, verschiedene Formen anzunehmen.<br />

Im Rahmen einer typisierten Sprache wie Eiffel bedeutet dies, daß Größen eines Programmtextes zur Laufzeit<br />

auf Exemplare verschiedener Klassen verweisen dürfen.<br />

So ist zum Beispiel vom intuitiven Verständnis her je<strong>der</strong> Arbeitnehmer auch eine Person – und nicht etwa<br />

etwas, was erst durch eine Konvertierung zu einer Person werden kann. Aufgrund des Vererbungskonzepts<br />

findet dieser intuitive Zusammenhang in Eiffel ein natürliches Gegenstück: eine Größe p vom Typ PERSON<br />

darf zur Laufzeit durchaus auf ein Arbeitnehmer- o<strong>der</strong> ein Universitätsangestellten-Objekt bezeichnen. Bei<br />

Programmiersprachen mit einem starren Typkonzept wäre hierfür eine explizite Konvertierung notwendig 26 .<br />

Polymorphismus ist in einer Sprache wie Eiffel leicht zu realisieren, da ja alle Größen eines Klassentyps in Wirklichkeit<br />

Verweise auf Objekte sind. Polymorphismus in Eiffel hat daher nichts zu tun mit Objekten, die ihre<br />

Form während <strong>der</strong> Laufzeit än<strong>der</strong>n, son<strong>der</strong>n bedeutet nur, daß eine gegebene Größe auf Objekte verschiedener<br />

Art verweisen kann. Durch Vererbung wird Polymorphismus also prinzipiell ermöglicht, aber gleichzeitig auch<br />

auf ein sinnvolles Maß begrenzt: eine Größe a vom Typ ARBEITNEHMER darf nicht ein einfaches Personenobjekt<br />

26 Eine einzige Ausnahme bilden Zahlen <strong>der</strong> Typen INTEGER und REAL, die in fast allen Sprachen automatisch ineinan<strong>der</strong><br />

umgewandelt werden, ohne daß es hierzu eines geson<strong>der</strong>ten Konvertierungsbefehls bedarf.

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!