22.08.2013 Aufrufe

Grundlagen der Informatik I “Programmierung”

Grundlagen der Informatik I “Programmierung”

Grundlagen der Informatik I “Programmierung”

MEHR ANZEIGEN
WENIGER ANZEIGEN

Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.

YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.

Eine Konsequenz dieser Regel ist, daß die oben beschriebene Situation als Namenskonflikt gilt, <strong>der</strong> durch<br />

Umbenennung beim Erben aufgelöst werden muß. Dies führt dann zur Vervielfältigung des features gemäß<br />

<strong>der</strong> Regel des wie<strong>der</strong>holten Erbens.<br />

Unter Berücksichtigung des wie<strong>der</strong>holten Erbens können wir jetzt das in Abschnitt 3.8.8 angesprochene Verbot<br />

von Namenskonflikten präzisieren.<br />

Entwurfsprinzip 3.8.14 (Umbenennungsregel)<br />

In einer Klasse K tritt ein Namenskonflikt auf, wenn zwei Eltern E1 und E2 von K ein feature mit<br />

demselben Namen f enthalten.<br />

Ein Namenskonflikt ist erlaubt, wenn f in einem gemeinsamen Vorfahren V von E1 und E2 erstmalig<br />

definiert wurde, auf keinem Vererbungspfad von V nach E1 und nach E2 umbenannt wurde und in seiner<br />

Typdeklaration an keine generischen Parameter von V gebunden ist.<br />

Nicht erlaubte Namenskonflikte müssen durch Umbenennung aufgelöst werden.<br />

Weitere Komplikationen bei wie<strong>der</strong>holtem Erben können durch Redefinition entstehen. Es kann sein, daß<br />

features auf verschiedenen Wegen zum gleichen Erben auch verschiedene Bedeutungen erlangt haben können.<br />

In diesem Fall liegt zwar keine Namenskollision im eigentlichen Sinne vor, aber die gemeinsame Nutzung<br />

würde dennoch zu Problemen führen, da dieses feature nun in mehreren Versionen geerbt wird.<br />

Bei einem Aufruf des features durch eine Größe, <strong>der</strong>en Typ die Ahnenklasse ist, kann nun keine eindeutige<br />

dynamische Bindung zwischen dem Originalnamen des Aufrufs und <strong>der</strong> tatsächlich zu verwendenen Implementierung<br />

mehr stattfinden. Auch Umbenennung löst dieses Problem nicht, da die Ahnenklasse die Namen<br />

nicht kennen kann, die eine Erbenklasse neu vergibt (die würde ja einen Eingriff in die Ahnenklasse beim<br />

Programmieren <strong>der</strong> Erben verlangen).<br />

In diesem Fall muß daher die Erbenklasse auswählen, welche Version des features dynamisch an frühere Versionen<br />

gebunden wird und welche nicht. Dies geschieht in Eiffel durch eine select-Unterklausel <strong>der</strong> entsprechenden<br />

Erbklausel. Eine solche Unterklausel beginnt mit dem Schlüsselwort select und listet danach die endgültigen<br />

Namen <strong>der</strong>jenigen features, welche dynamisch an frühere Versionen gebunden werden sollen. Nicht selektierte<br />

Versionen sind nur von den Nachfolgerklassen, nicht aber von den Ahnen her erreichbar.<br />

[Meyer, 1992, Kapitel 11] liefert eine detaillierte Betrachtung des wie<strong>der</strong>holten Erbens und die genaue Festlegung<br />

weiterer Son<strong>der</strong>fälle. Wir wollen im Rahmen dieser Veranstaltung nicht weiter darauf eingehen. Wie<strong>der</strong>holtes<br />

Erben wird in <strong>der</strong> Praxis nicht sehr häufig gebraucht. Eine Systemkonfiguration muß schon verhältnismäßig<br />

komplex sein, bevor diese Einrichtung wirklich benötigt wird.<br />

In unkomplizierten Fällen ensteht wie<strong>der</strong>holtes Erben eher durch einen Anfängerfehler, bei dem die Transitivität<br />

<strong>der</strong> Vererbung ignoriert wird. Oft wird zum Beispiel die Klasse STD FILES explizit mit in die Erbklausel<br />

aufgenommen, um sicherzustellen, daß Ein- und Ausgabekommandos unqualifiziert genutzt werden können.<br />

Dabei wird vergessen, daß diese Klasse bereits Vorfahre an<strong>der</strong>er Klassen ist, die man ebenfalls beerbt. Die<br />

Aufzählung von STD FILES wird also überflüssig. Aufgrund <strong>der</strong> Regel des Wie<strong>der</strong>holten Erbens ist dies aber<br />

nur ein uneleganter Programmierstil, <strong>der</strong> nicht zu einem Fehler führt.<br />

3.8.10 Vererbung und Zusicherungen<br />

Am Ende des Abschnitts 3.8.4 hatten wir bereits darauf hingewiesen, daß Redefinition prinzipiell die Möglichkeit<br />

einer kompletten Verän<strong>der</strong>ung <strong>der</strong> Semantik ererbter features ermöglicht. Dies birgt natürlich das Risiko<br />

eines Mißbrauchs in sich, <strong>der</strong> gerade durch das dynamische Binden sehr gefährlich werden könnte. Dies kann<br />

nur durch ein enges Zusammenspiel von Zusicherungen und Vererbung verhin<strong>der</strong>t werden. Die Grundregel<br />

hierfür haben wir bereits öfter angedeutet:<br />

Was die Ahnen versprechen, müssen die Erben erfüllen!

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

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!