Grundlagen der Informatik I “Programmierung”
Grundlagen der Informatik I “Programmierung”
Grundlagen der Informatik I “Programmierung”
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!