Informatik-Lexikon |
Datenkapselung |
Beispiel für AnfängerWenn Sie in einem Auto fahren, so wollen Sie sich auf den Verkehr konzentrieren und nicht ständig darüber nachdenken, wie die Gangschaltung oder das Gaspedal funktionieren. Das würde sie nur ablenken und zu Fehlern verführen. Es reicht, wenn Sie wissen, wo das Gaspedal ist und wie man es bedient bzw. wie Sie die Gänge richtig einlegen. Die Einzelheiten der Mechanik sehen sie nicht, denn sie sind vor Ihnen verborgen. Analog verfährt man, wenn man programmiert. Wenn Sie eine Linie zeichnen wollen, so reicht es völlig aus, wenn Sie wissen, dass es den drawLine-Befehl gibt und wie er aufgerufen wird. Mit welchem mathematischen Algorithmus der Befehl die Linie zeichnet, interessiert nicht. Dieses seit langem bewährte Programmierprinzip heißt Datenkapselung. Die inneren Details einer Klasse werden eingekapselt und dadurch vor der Außenwelt verborgen. Dazu betrachten wir einmal folgende Quelltexte:
1 Datenkapselung konkret Die Abbildung 1 zeigt den Quelltext von zwei Klassen Gangschaltung und Auto, zwischen denen eine Hat-Beziehung besteht: Jedes Objekt der Klasse Auto hat eine Gangschaltung gs der Klasse Gangschaltung. Die Klasse Gangschaltung hat wiederum ein Attribut gang, welches als privat deklariert ist. Welche Folgen dies hat, zeigt die Fehlermeldung im Fenster der Klasse Auto: Der Befehl System.out.println(gs.gang); kann nicht auf das Attribut gang des Objektes gs zugreifen. Das Attribut gang ist eine "rein interne Angelegenheit" der Klasse Gangschaltung. Niemand, der die Klasse verwendet, muss wissen, wie die Gänge oder die Gangwechsel innerhalb dieser Klasse realisiert wurden - solange die Klasse das macht, was sie machen soll. Man spricht hier von information hiding oder Datenkapselung. Würde man dagegen schreiben System.out.println(gs.getGang()); so würde das Programm fehlerfrei funktionieren. Bei getGang() handelt es sich nämlich um eine Methode, die als public - öffentlich - deklariert wurde. Alternativ hätte man natürlich das Attribut gang der Klasse Gangschaltung als public deklarieren können. Dann wäre dieses Attribut aber nicht mehr gekapselt. Das wäre dann so, als würden Sie beim Autofahren ständig die Mechanik der Gangschaltung vor sich sehen. Bei der Datenkapselung verfolgt man also das Ziel, die Attribute einer Klasse vor unerlaubten Zugriffen von außen zu schützen. Ein so geschütztes Attribut kann nicht aus Versehen verändert werden, was bei einem großen Programm sonst unweigerlich früher oder später passieren würde. In der Tat ist die Datenkapselung entwickelt worden, als die Anwendungsprogramme immer größer und unübersichtlicher wurden. Die Datenkapselung stellt einen wirksamen Schutz gegen die eigenen Programmierfehler dar: Was man nicht kennt oder sieht, kann man auch nicht aus Versehen verändern. |
Beispiel für FortgeschritteneEin zweites Beispiel soll die Vorzüge der Datenkapselung demonstrieren. Wenn Sie dieses Beispiel verstehen wollen, müssen Sie sich allerdings bereits mit Arrays, Zeigertypen und dem Prinzip der Vererbung auseinandergesetzt haben. Eine Stackmaschine ist ein Stack, der rechnen kann. Die Klasse Stackmaschine ist eine Tochterklasse der Klasse Stack, erbt also alle Attribute und Methoden der Klasse Stack. Betrachten wir nun die Implementation der add()-Methode der Klasse Stackmaschine: public void add()
{
double ergebnis = top();
pop();
ergebnis += top();
pop();
push(ergebnis);
}
In der Klasse Stack wurde der eigentliche Datenspeicher mit Hilfe eines Arrays von double-Zahlen implementiert. Theoretisch könnte die add()-Methode also direkt auf das oberste und zweitoberste Arrayelement über die Indices 0 und 1 zugreifen; der Quelltext der add()-Methode würde sich so eventuell stark verkürzen. Ein solches Vorgehen würde aber zwingend voraussetzen, dass die Klasse Stack den Datenspeicher tatsächlich mit Hilfe eines solchen Arrays implementiert hat. Was wäre aber, wenn der Stack mit Hilfe von Zeigertypen oder auf eine andere Weise realisiert wurde? Dann hätte der Programmierer, der add() auf diese Weise programmieren wollte, eben Pech gehabt? Ein solches Pech kann man vermeiden, indem man ausschließlich die "offiziell zugelassenen" Methoden einer Klasse benutzt. Bei der Klasse Stack sind die Methoden top(), push() und pop() offiziell zugelassen. Die Methode top() liefert immer den Wert des obersten Stackelementes, egal, ob der Stack mit Hilfe eines Arrays oder mit Hilfe einer linearen dynamischen Liste realisiert wurde. Die Methode funktioniert auf jeden Fall. Und pop() entfernt immer das oberste Stackelement, egal, ob es ein Arrayelement mit dem Index 0 ist oder das erste Element einer dynamischen Liste. Der obige Quelltext hält sich streng an das Prinzip der Datenkapselung. Es wird nur auf die "offziellen" Schnittstellen-Methoden der Klasse Stack zugegriffen. Ein direkter Zugriff auf interne Datenstrukturen der Klasse Stack findet dagegen nicht statt. |