diff options
| author | Sven Eisenhauer <sven@sven-eisenhauer.net> | 2023-11-10 15:11:48 +0100 |
|---|---|---|
| committer | Sven Eisenhauer <sven@sven-eisenhauer.net> | 2023-11-10 15:11:48 +0100 |
| commit | 33613a85afc4b1481367fbe92a17ee59c240250b (patch) | |
| tree | 670b842326116b376b505ec2263878912fca97e2 /Master/Reference Architectures and Patterns/hjp5/html/k100047.html | |
| download | Studium-33613a85afc4b1481367fbe92a17ee59c240250b.tar.gz Studium-33613a85afc4b1481367fbe92a17ee59c240250b.tar.bz2 | |
Diffstat (limited to 'Master/Reference Architectures and Patterns/hjp5/html/k100047.html')
| -rw-r--r-- | Master/Reference Architectures and Patterns/hjp5/html/k100047.html | 609 |
1 files changed, 609 insertions, 0 deletions
diff --git a/Master/Reference Architectures and Patterns/hjp5/html/k100047.html b/Master/Reference Architectures and Patterns/hjp5/html/k100047.html new file mode 100644 index 0000000..17da888 --- /dev/null +++ b/Master/Reference Architectures and Patterns/hjp5/html/k100047.html @@ -0,0 +1,609 @@ +<html>
+<head>
+<title>
+Handbuch der Java-Programmierung, 5. Auflage
+</title>
+</head>
+<body>
+<a name="startofbody"></a>
+<script language="JavaScript" src="hjp4lib.js">
+</script>
+<script language="JavaScript">
+installKbdHandler("97,#startofbody;101,#endofbody;116,cover.html;122,k100003.html;115,search.html;105,index.html;100,JDKDOCS;112,APIDOCS;104,k100046.html;106,k100046.html;107,k100048.html;108,k100051.html");
+</script>
+<table border=0 cellpadding=0 cellspacing=1 width="100%">
+<tr bgcolor="#EEFFCC">
+<td width="7%" align=center bgcolor="#DDCC99"><a href="cover.html"> Titel </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100003.html"> Inhalt </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="search.html"> Suchen </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="index.html"> Index </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/index.html" onClick="this.href=getDocIndex()"> DOC </a>
+<td align="right">Handbuch der Java-Programmierung, 5. Auflage
+<tr bgcolor="#EEFFCC">
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100046.html"> << </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100046.html"> < </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100048.html"> > </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100051.html"> >> </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/api/index.html" onClick="this.href=getApiIndex()"> API </a>
+<td align="right">Kapitel 7 - OOP I: Grundlagen
+</table>
+<hr>
+
+
+<!-- Section -->
+<a name="sectlevel2id007001"></a>
+<h2>7.1 Konzepte objektorientierter Programmiersprachen </h2>
+<hr>
+<ul>
+<li><a href="k100047.html#sectlevel2id007001">7.1 Konzepte objektorientierter Programmiersprachen</a>
+<ul>
+<li><a href="k100047.html#sectlevel3id007001001">7.1.1 Einführung</a>
+<li><a href="k100047.html#sectlevel3id007001002">7.1.2 Abstraktion</a>
+<li><a href="k100047.html#kapselung">7.1.3 Kapselung</a>
+<li><a href="k100047.html#sectlevel3id007001004">7.1.4 Wiederverwendung</a>
+<li><a href="k100047.html#sectlevel3id007001005">7.1.5 Beziehungen</a>
+<ul>
+<li><a href="k100047.html#sectlevel4id007001005001">Generalisierung und Spezialisierung</a>
+<li><a href="k100047.html#sectlevel4id007001005002">Aggregation und Komposition</a>
+<li><a href="k100047.html#sectlevel4id007001005003">Verwendungs- und Aufrufbeziehungen</a>
+</ul>
+<li><a href="k100047.html#polymorphismus">7.1.6 Polymorphismus</a>
+<li><a href="k100047.html#sectlevel3id007001007">7.1.7 Fazit</a>
+</ul>
+</ul>
+<hr>
+
+
+<!-- Section -->
+<a name="sectlevel3id007001001"></a>
+<h3>7.1.1 Einführung </h3>
+
+<p>
+<a name="ixa100437">Objektorientierte Programmierung</a> (kurz <a name="ixa100438"><i>OOP</i></a>)
+ist <i>das</i> Programmierparadigma der 90er Jahre. Viele der heute
+verwendeten Programmiersprachen sind entweder von Grund auf objektorientiert
+(Java, Eiffel, SmallTalk) oder wurden im Laufe der Zeit mit objektorientierten
+Erweiterungen versehen (Basic, Pascal, ADA). Selbst manche Scriptsprachen
+erlauben den Zugriff auf (mitunter vordefinierte) Objekte oder besitzen
+objektorientierte Eigenschaften (JavaScript, Python). Die objektorientierte
+Programmierung war eine der »Silver Bullets«, die die Software-Industrie
+aus ihrer Krise führen und zu robusteren, fehlerärmeren
+und besser wartbaren Programmen führen sollte.
+
+<p>
+Was sind nun die Geheimnisse der objektorientierten Programmierung?
+Was verbirgt sich hinter dem Begriff, und welches sind seine wichtigsten
+Konzepte? Wir wollen uns zunächst mit den Grundideen objektorientierter
+Programmierung auseinandersetzen und dann in diesem und den nächsten
+Kapiteln Schritt für Schritt erläutern, wie sie in Java
+umgesetzt wurden.
+
+<!-- Section -->
+
+<a name="sectlevel3id007001002"></a>
+<h3>7.1.2 Abstraktion </h3>
+
+<p>
+Eine der wichtigsten Ideen der objektorientierten Programmierung ist
+die Trennung zwischen <i>Konzept</i> und <i>Umsetzung</i>, etwa zwischen
+einem <i>Bauteil</i> und seinem <i>Bauplan</i>, einer <i>Speise</i>
+und dem für die Zubereitung erforderlichen <i>Rezept</i> oder
+einem <i>technischen Handbuch</i> und der <i>konkreten Apparatur</i>,
+die dadurch beschrieben wird. Diese Art von Unterscheidung ist in
+der wirklichen Welt sehr bedeutsam. Wer weiß, wie man <i>einen
+einzigen</i> Lichtschalter bedient, kann andere, gleichartige Schalter
+ebenfalls bedienen. Wer ein Rezept für eine Sachertorte besitzt,
+ist in der Lage, diese zu backen, selbst wenn er ansonsten über
+keine Koch- oder Backkünste verfügt. Wer einen Führerschein
+gemacht hat, kann ein Auto fahren, ohne im Detail über das komplizierte
+Innenleben desselben unterrichtet zu sein.
+
+<p>
+In der objektorientierten Programmierung manifestiert sich diese Unterscheidung
+in den Begriffen <i>Objekt</i> und <i>Klasse</i>. Ein Objekt ist ein
+tatsächlich existierendes »Ding« aus der Anwendungswelt
+des Programms. Es spielt dabei keine Rolle, ob es sich um die programmierte
+Umsetzung eines konkret existierenden Gegenstandes handelt, oder ob
+»nur« ein abstraktes Konzept modelliert wird. Eine »Klasse«
+ist dagegen die Beschreibung eines oder mehrerer ähnlicher Objekte.
+»Ähnlich« bedeutet dabei, dass eine Klasse nur Objekte
+eines bestimmten Typs beschreibt. Diese müssen sich zwar nicht
+in allen Details gleichen, aber doch in so vielen von ihnen übereinstimmen,
+dass eine gemeinsame Beschreibung angebracht ist. Eine Klasse beschreibt
+mindestens drei wichtige Dinge:
+<ul>
+<li>Wie ist das Objekt zu bedienen?
+<li>Welche Eigenschaften hat das Objekt und wie verhält es sich?
+<li>Wie wird das Objekt hergestellt?
+</ul>
+
+<p>
+Ähnlich wie ein Rezept zur Herstellung von Hunderten von Sachertorten
+verwendet werden kann, ermöglicht eine Klasse das Erzeugen einer
+prinzipiell beliebigen Anzahl von Objekten. Jedes hat dabei seine
+eigene Identität und mag sich in gewissen Details von allen anderen
+unterscheiden. Letzlich ist das Objekt aber immer eine <i>Instanz</i>
+der Klasse, nach der es modelliert wurde. In einem Haus kann es beispielsweise
+fünfzig Lichtschalter-Objekte geben. Sie alle sind Instanzen
+der Klasse »Lichtschalter«, lassen sich in vergleichbarer
+Weise bedienen und sind identisch konstruiert. Dennoch unterscheiden
+wir sehr wohl zwischen dem Lichschalter-Objekt, das die Flurbeleuchtung
+bedient, und jenem, das den Keller erhellt. Und beide widerum unterscheiden
+sich eindeutig von allen anderen Lichschalterinstanzen im Haus.
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+Es ist übrigens kein Zufall, dass wir die Begriffe »Instanz«
+und »Objekt« synonym verwenden. In der objektorientierten
+Programmierung ist das sehr verbreitet (auch wenn Puristen zwischen
+beiden Begriffen noch Unterschiede sehen), und wir wollen uns diesem
+Wortgebrauch anschließen.</td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#000077">
+<tr>
+<td><font color="#FFFFFF"> Hinweis </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+
+<p>
+Diese Unterscheidung zwischen Objekten und Klassen kann als <a name="ixa100439"><i>Abstraktion</i></a>
+angesehen werden. Sie bildet die erste wichtige Eigenschaft objektorientierter
+Sprachen. Abstraktion hilft, Details zu ignorieren, und reduziert
+damit die Komplexität des Problems. Die Fähigkeit zur Abstraktion
+ist eine der wichtigsten Voraussetzungen zur Beherrschung komplexer
+Apparate und Techniken und kann in seiner Bedeutung nicht hoch genug
+eingeschätzt werden.
+
+<!-- Section -->
+
+<a name="kapselung"></a>
+<h3>7.1.3 Kapselung </h3>
+
+<p>
+In objektorientierten Programmiersprachen wird eine Klasse durch die
+Zusammenfassung einer Menge von Daten und darauf operierender Funktionen
+(die nun <a name="ixa100440"><i>Methoden</i></a> genannt werden) definiert.
+Die Daten werden durch einen Satz Variablen repräsentiert, der
+für jedes instanziierte Objekt neu angelegt wird (diese werden
+als <a name="ixa100441"><i>Attribute</i></a>, <a name="ixa100442"><i>Membervariablen</i></a>,
+<a name="ixa100443"><i>Instanzvariablen</i></a> oder <a name="ixa100444"><i>Instanzmerkmale</i></a>
+bezeichnet). Die Methoden sind im ausführbaren Programmcode nur
+einmal vorhanden, operieren aber bei jedem Aufruf auf den Daten eines
+ganz bestimmten Objekts (das Laufzeitsystem übergibt bei jedem
+Aufruf einer Methode einen Verweis auf den Satz Instanzvariablen,
+mit dem die Methode gerade arbeiten soll).
+
+<p>
+Die Instanzvariablen repräsentieren den <i>Zustand</i> eines
+Objekts. Sie können bei jeder Instanz einer Klasse unterschiedlich
+sein und sich während seiner Lebensdauer verändern. Die
+Methoden repräsentieren das <i>Verhalten</i> des Objekts. Sie
+sind - von gewollten Ausnahmen abgesehen, bei denen Variablen bewußt
+von außen zugänglich gemacht werden - die einzige Möglichkeit,
+mit dem Objekt zu kommunizieren und so Informationen über seinen
+Zustand zu gewinnen oder diesen zu verändern. Das Verhalten der
+Objekte einer Klasse wird in seinen Methodendefinitionen festgelegt
+und ist von dem darin enthaltenen Programmcode und dem aktuellen Zustand
+des Objekts abhängig.
+
+<p>
+Diese Zusammenfassung von Methoden und Variablen zu Klassen bezeichnet
+man als <a name="ixa100445"><i>Kapselung</i></a>. Sie stellt die zweite
+wichtige Eigenschaft objektorientierter Programmiersprachen dar. Kapselung
+hilft vor allem, die Komplexität der Bedienung eines Objekts
+zu reduzieren. Um eine Lampe anzuschalten, muss man nicht viel über
+den inneren Aufbau des Lichtschalters wissen. Sie vermindert aber
+auch die Komplexität der Implementierung, denn undefinierte Interaktionen
+mit anderen Bestandteilen des Programms werden verhindert oder reduziert.
+
+
+<!-- Section -->
+<a name="sectlevel3id007001004"></a>
+<h3>7.1.4 Wiederverwendung </h3>
+
+<p>
+Durch die Abstraktion und Kapselung wird die <a name="ixa100446"><i>Wiederverwendung</i></a>
+von Programmelementen gefördert, die dritte wichtige Eigenschaft
+objektorientierter Programmiersprachen. Ein einfaches Beispiel dafür
+sind <i>Collections</i>, also Objekte, die Sammlungen anderer Objekte
+aufnehmen und auf eine bestimmte Art und Weise verarbeiten können.
+Collections sind oft sehr kompliziert aufgebaut (typischerweise zur
+Geschwindigkeitssteigerung oder Reduzierung des Speicherbedarfs),
+besitzen aber in aller Regel eine einfache Schnittstelle. Werden sie
+als Klasse implementiert und werden durch die Kapselung der Code-
+und Datenstrukturen die komplexen Details »wegabstrahiert«,
+können sie sehr einfach wiederverwendet werden. Immer, wenn im
+Programm eine entsprechende Collection benötigt wird, muss lediglich
+ein Objekt der passenden Klasse instanziert werden, und das Programm
+kann über die einfach zu bedienende Schnittstelle darauf zugreifen.
+Wiederverwendung ist ein wichtiger Schlüssel zur Erhöhung
+der Effizienz und Fehlerfreiheit beim Programmieren.
+
+<!-- Section -->
+
+<a name="sectlevel3id007001005"></a>
+<h3>7.1.5 Beziehungen </h3>
+
+<p>
+Objekte und Klassen existieren für gewöhnlich nicht völlig
+alleine, sondern stehen in Beziehungen zueinander. So ähnelt
+ein Fahrrad beispielsweise einem Motorrad, hat aber auch mit einem
+Auto Gemeinsamkeiten. Ein Auto ähnelt dagegen einem Lastwagen.
+Dieser kann einen Anhänger haben, auf dem ein Motorrad steht.
+Ein Fährschiff ist ebenfalls ein Transportmittel und kann viele
+Autos oder Lastwagen aufnehmen, genauso wie ein langer Güterzug.
+Dieser wird von einer Lokomotive gezogen. Ein Lastwagen kann auch
+einen Anhänger ziehen, muss es aber nicht. Bei einem Fährschiff
+ist keine Zugmaschine erforderlich, und es kann nicht nur Transportmittel
+befördern, sondern auch Menschen, Tiere oder Lebensmittel.
+
+<p>
+Wir wollen ein wenig Licht in diese Beziehungen bringen und zeigen,
+wie sie sich in objektorientierten Programmiersprachen auf wenige
+Grundtypen reduzieren lassen:
+<ul>
+<li>»is-a«-Beziehungen (Generalisierung, Spezialisierung)
+<li>»part-of«-Beziehungen (Aggregation, Komposition)
+<li>Verwendungs- oder Aufrufbeziehungen
+</ul>
+
+
+<!-- Section -->
+<a name="sectlevel4id007001005001"></a>
+<h4>Generalisierung und Spezialisierung </h4>
+
+<p>
+Zuerst wollen wir die »is-a«-Beziehung betrachten. »is-a«
+bedeutet »ist ein« und meint die Beziehung zwischen »ähnlichen«
+Klassen. Ein Fahrrad ist kein Motorrad, aber beide sind Zweiräder.
+Ein Zweirad, und damit sowohl das Fahrrad als auch das Motorrad, ist
+ein Straßenfahrzeug, ebenso wie das Auto und der Lastwagen.
+All diese Klassen repräsentieren Transportmittel, zu denen aber
+auch die Schiffe und Güterzüge zählen.
+
+<p>
+Die »is-a«-Beziehung zwischen zwei Klassen <i>A</i> und
+<i>B</i> sagt aus, dass »<i>B</i> ein <i>A</i> ist«, also
+alle Eigenschaften von <i>A</i> besitzt, und vermutlich noch ein paar
+mehr. <i>B</i> ist demnach eine Spezialisierung von <i>A</i>. Andersherum
+betrachtet, ist <i>A</i> eine Generalisierung (Verallgemeinerung)
+von <i>B</i>.
+
+<p>
+»is-a«-Beziehungen werden in objektorientierten Programmiersprachen
+durch <a name="ixa100447"><i>Vererbung</i></a> ausgedrückt. Eine
+Klasse wird dabei nicht komplett neu definiert, sondern von einer
+anderen Klasse <i>abgeleitet</i>. In diesem Fall erbt sie alle Eigenschaften
+dieser Klasse und kann nach Belieben eigene hinzufügen. In unserem
+Fall wäre also <i>B</i> von <i>A</i> abgeleitet. <i>A</i> wird
+als <a name="ixa100448"><i>Basisklasse</i></a> (manchmal auch als
+<a name="ixa100449"><i>Vaterklasse</i></a>), <i>B</i> als <a name="ixa100450"><i>abgeleitete
+Klasse</i></a> bezeichnet.
+
+<p>
+Vererbungen können mehrstufig sein, d.h. eine abgeleitete Klasse
+kann Basisklasse für weitere Klassen sein. Auf diese Weise können
+vielstufige <i>Vererbungshierarchien</i> entstehen, die in natürlicher
+Weise die Taxonomie (also die gegliederte Begriffsstruktur) der zu
+modellierenden Anwendungswelt repräsentieren. Vererbungshierarchien
+werden wegen ihrer Baumstruktur auch als <a name="ixa100451"><i>Ableitungsbäume</i></a>
+bezeichnet. Sie werden meist durch Graphen dargestellt, in denen die
+abgeleiteten Klassen durch Pfeile mit den Basisklassen verbunden sind
+und die Basisklassen oberhalb der abgeleiteten Klassen stehen. Für
+unsere Fahrzeugwelt ergäbe sich beispielsweise folgender Ableitungsbaum:
+<p>
+<a name="transportmittel"></a>
+<img src="images/VererbTransp.gif">
+<p>
+
+<p><i>
+Abbildung 7.1: Vererbungshierarchie für Transportmittel</i></p>
+
+<p>
+Als Eigenschaften der Basisklasse <i>Transportmittel</i> könnten
+etwa dessen Anschaffungskosten, seine Lebensdauer oder die Transportgeschwindigkeit
+angesehen werden. Sie gelten für alle abgeleiteten Klassen. In
+der zweiten Ableitungsebene unterscheiden wir nach der Art der Fortbewegung
+(wir hätten allerdings ebensogut nach der Farbe, dem Verwendungszweck
+oder einem beliebigen anderen Merkmal unterscheiden können).
+In der Klasse <i>Wasserfahrzeug</i> könnten nun Eigenschaften
+wie Verdrängung, Hochseetauglichkeit und erforderliche Besatzung
+festgehalten werden. Das Fährschiff schließlich fügt
+seine Transportkapazitäten für Autos, Lastwagen und Personen
+hinzu, gibt die Anzahl der Kabinen der unterschiedlichen Kategorien
+an und definiert, ob es im RORO-Verfahren be- und entladen werden
+kann oder nicht.
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+In manchen objektorientierten Programmiersprachen kann eine abgeleitete
+Klasse mehr als eine Basisklasse besitzen (z.B. in C++ oder Eiffel).
+In diesem Fall spricht man von <a name="ixa100452"><i>Mehrfachvererbung</i></a>.
+Die Vererbungshierarchie ist dann nicht mehr zwangsläufig ein
+Baum, sondern muss zu einem gerichteten Graph verallgemeinert werden.
+In Java gibt es allerdings keine Mehrfachvererbung, und wir wollen
+daher nicht weiter auf die Besonderheiten dieser Technik eingehen.</td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#000077">
+<tr>
+<td><font color="#FFFFFF"> Hinweis </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+
+
+<!-- Section -->
+<a name="sectlevel4id007001005002"></a>
+<h4>Aggregation und Komposition </h4>
+
+<p>
+Der zweite Beziehungstyp, die »part-of«-Beziehungen, beschreibt
+die <i>Zusammensetzung</i> eines Objekts aus anderen Objekten (dies
+wird auch als <a name="ixa100453"><i>Komposition</i></a> bezeichnet).
+So besteht beispielsweise der Güterzug aus einer (oder manchmal
+zwei) Lokomotiven und einer großen Anzahl Güterzuganhänger.
+Der Lastwagen besteht aus der LKW-Zugmaschine und eventuell einem
+Anhänger. Ein Fahrrad besteht aus vielen Einzelteilen. Objektorientierte
+Sprachen implementieren »part-of«-Beziehungen durch Instanzvariablen,
+die Objekte aufnehmen können. Der Güterzug könnte also
+eine (oder zwei) Instanzvariablen vom Typ <i>Lokomotive</i> und ein
+Array von Instanzvariablen vom Typ <i>Güterzuganhänger</i>
+besitzen.
+
+<p>
+»part-of«-Beziehungen müssen nicht zwangsläufig
+beschreiben, <i>woraus</i> ein Objekt zusammengesetzt ist. Vielmehr
+können sie auch den allgemeineren Fall des <i>einfachen Aufnehmens</i>
+anderer Objekte beschreiben (was auch als <a name="ixa100454"><i>Aggregation</i></a>
+bezeichnet wird). Zwischen dem Motorrad, das auf dem Lastwagenanhänger
+steht, oder den Straßenfahrzeugen, die auf einem Fährschiff
+untergebracht sind, besteht zwar eine »part-of«-Beziehung,
+sie ist aber nicht <i>essentiell</i> für die Existenz des aufnehmenden
+Objekts. Der Anhänger existiert auch wenn kein Motorrad darauf
+platziert ist. Und das Fährschiff kann auch leer von Kiel nach
+Oslo fahren.
+
+<p>
+Während bei der objektorientierten Modellierung sorgsam zwischen
+beiden Fällen unterschieden wird (Komposition bezeichnet die
+strenge Form der Aggregation auf Grund einer existentiellen Abhängigkeit),
+behandeln objektorientierte Programmiersprachen sie prinzipiell gleich.
+In beiden Fällen gibt es Instanzvariablen, die Objekte aufnehmen
+können. Ist ein optionales Objekt nicht vorhanden, wird dies
+durch die Zuweisung eines speziellen <a name="ixa100455"><i>null-Objekts</i></a>
+ausgedrückt. Für die semantischen Eigenschaften der Beziehung
+ist die Klasse selbst verantwortlich.
+
+<!-- Section -->
+
+<a name="sectlevel4id007001005003"></a>
+<h4>Verwendungs- und Aufrufbeziehungen </h4>
+
+<p>
+Die dritte Art von Beziehungen zwischen Objekten oder Klassen hat
+den allgemeinsten Charakter. Benutzt beispielsweise eine Methode während
+ihrer Ausführung ein temporäres Objekt, so besteht zwischen
+beiden eine Verwendungsbeziehung: Objekt <i>x</i> verwendet eine Instanz
+der Klasse <i>Y</i>, um bestimmte Operationen auszuführen. Taucht
+in der Argumentliste einer Methode eine Objektvariable der Klasse
+<i>T</i> auf, so entsteht eine ähnliche Beziehung zu <i>T</i>.
+Zwar ist dies keine »part-of«-Beziehung, und auch die Ableitungsbeziehung
+zwischen beiden Klassen spielt keine Rolle. Wenigstens muss aber die
+Methode die Argumentklasse kennen und in der Lage sein, Methoden darauf
+aufzurufen oder das Objekt an Dritte weiterzugeben.
+
+<p>
+Allgemeine Verwendungs- oder Aufrufbeziehungen finden in objektorientierten
+Programmiersprachen ihren Niederschlag darin, dass Objekte als lokale
+Variablen oder Methodenargumente verwendet werden. Sie werden auch
+mit dem Begriff <a name="ixa100456"><i>Assoziationen</i></a> bezeichnet.
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+In den vorangegangenen Abschnitten wurden mehrfach die Begriffe <i>Membervariable</i>,
+<i>Instanzvariable</i> und <i>Objektvariable</i> verwendet. Als <a name="ixa100457"><i>Objektvariable</i></a>
+bezeichnen wir stets eine Variable, die ein Objekt aufnehmen kann,
+also vom Typ einer Klasse ist. Das Gegenteil einer Objektvariable
+ist eine primitive Variable <a name="ixa100458"></a>. Die Begriffe
+<i>Membervariable</i> und <i>Instanzvariable</i> werden synonym verwendet.
+Sie bezeichnen eine Variable, die innerhalb einer Klasse definiert
+wurde und mit jeder Instanz neu angelegt wird.</td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#000077">
+<tr>
+<td><font color="#FFFFFF"> Hinweis </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+
+
+<!-- Section -->
+<a name="polymorphismus"></a>
+<h3>7.1.6 Polymorphismus </h3>
+
+<p>
+Als letztes wichtiges Konzept objektorientierter Programmiersprachen
+wollen wir uns mit dem <a name="ixa100459"><i>Polymorphismus</i></a>
+beschäftigen. Polymorphismus bedeutet direkt übersetzt etwa
+»Vielgestaltigkeit« und bezeichnet zunächst einmal
+die Fähigkeit von Objektvariablen, Objekte unterschiedlicher
+Klassen aufzunehmen. Das geschieht allerdings nicht unkontrolliert,
+sondern beschränkt sich für eine Objektvariable des Typs
+<i>X</i> auf alle Objekte der Klasse <i>X</i> oder einer daraus abgeleiteten
+Klasse.
+
+<p>
+Eine Objektvariable vom Typ <i>Straßenfahrzeug</i> kann also
+nicht nur Objekte der Klasse <i>Straßenfahrzeug</i> aufnehmen,
+sondern auch Objekte der Klassen <i>Zweirad</i>, <i>Vierrad</i>, <i>Anhänger</i>,
+<i>Motorrad</i>, <i>Fahrrad</i>, <i>Auto</i> und <i>Lastwagen</i>.
+Diese auf den ersten Blick erstaunliche Lässigkeit entspricht
+allerdings genau dem gewohnten Umgang mit Vererbungsbeziehungen. Ein
+<i>Zweirad</i> ist nunmal ein <i>Straßenfahrzeug</i>, hat alle
+Eigenschaften eines Straßenfahrzeugs und kann daher durch eine
+Variable repräsentiert werden, die auf ein Straßenfahrzeug
+verweist. Daß es möglicherweise ein paar zusätzliche
+Eigenschaften besitzt, stört den Compiler nicht. Er hat nur sicherzustellen,
+dass die Eigenschaften eines Straßenfahrzeugs vollständig
+vorhanden sind, denn mehr stellt er dem Programm beim Zugriff auf
+eine Variable dieses Typs nicht zur Verfügung. Davon kann er
+aber aufgrund der Vererbungshierarchie ausgehen.
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+Anders herum funktioniert Polymorphismus nicht. Wäre es beispielsweise
+möglich, einer Variable des Typs <i>Motorrad</i> ein Objekt des
+Typs <i>Zweirad</i> zuzuzweisen, könnte das Laufzeitsystem in
+Schwierigkeiten geraten. Immer wenn auf der <i>Motorrad</i>-Variablen
+eine Eigenschaft benutzt würde, die in der Basisklasse <i>Zweirad</i>
+noch nicht vorhanden ist, wäre das Verhalten des Programms undefiniert,
+wenn zum Ausführungszeitpunkt nicht ein <i>Motorrad</i>, sondern
+ein Objekt aus der Basisklasse darin gespeichert wäre.</td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#000077">
+<tr>
+<td><font color="#FFFFFF"> Hinweis </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+
+<p>
+Interessant wird Polymorphismus, wenn die Programmiersprache zusätzlich
+das Konzept des <a name="ixa100460"><i>Late Binding</i></a> implementiert.
+Im Unterschied zum »Early Binding« wird dabei nicht bereits
+zur Compilezeit entschieden, welche Ausprägung einer bestimmten
+Methode aufgerufen werden soll, sondern erst zur Laufzeit. Wenn beispielsweise
+auf einem Objekt der Klasse <i>X</i> eine Methode mit dem Namen <i>f</i>
+aufgerufen werden soll, ist zwar prinzipiell bereits zur Compilezeit
+klar, wie der Name lautet. Objektorientierte Programmiersprachen erlauben
+aber das <a name="ixa100461"><i>Überlagern</i></a> von Methoden
+in abgeleiteten Klassen, und da - wie zuvor erwähnt - eine Objektvariable
+des Typs <i>X</i> auch Objekte aus allen von <i>X</i> abgeleiteten
+Klassen aufnehmen kann, könnte <i>f</i> in einer dieser nachgelagerten
+Klassen überlagert worden sein. Welche konkrete Methode also
+aufgerufen werden muss, kann damit erst zur Laufzeit entschieden werden.
+Wir werden in <a href="k100055.html#abstraktpolymorph">Abschnitt 8.4</a>
+ein ausführliches Anwendungsbeispiel vorstellen.
+
+<p>
+Nun ist dieses Verhalten keinesfalls hinderlich oder unerwünscht,
+sondern kann sehr elegant dazu genutzt werden, automatische typbasierte
+Fallunterscheidungen vorzunehmen. Betrachten wir dazu noch einmal
+unsere Hierarchie von Transportmitteln. Angenommen, unser Unternehmen
+verfügt über einen breit gefächerten Fuhrpark von Transportmitteln
+aus allen Teilen des Ableitungsbaums. Als Unternehmer interessieren
+uns natürlich die Kosten jedes Transportmittels pro Monat, und
+wir würden dazu eine Methode <i>getMonatsKosten</i> in der Basisklasse
+<i>Transportmittel</i> definieren. Ganz offensichtlich läßt
+sich diese dort aber nicht <i>implementieren</i>, denn beispielsweise
+die Berechnung der monatlichen Kosten unseres Fährschiffes gestaltet
+sich ungleich schwieriger als die der drei Fahrräder, die auch
+im Fahrzeugfundus sind.
+
+<p>
+Anstatt nun in aufwändigen Fallunterscheidungen für jedes
+Objekt zu prüfen, von welchem Typ es ist, muss lediglich diese
+Methode in jeder abgeleiteten Klasse implementiert werden. Besitzt
+das Programm etwa ein Array von <i>Transportmittel</i>-Objekten, kann
+dieses einfach durchlaufen und für jedes Element <i>getMonatsKosten</i>
+aufgerufen werden. Das Laufzeitsystem kennt den jeweiligen konkreten
+Typ und kann die korrekte Methode aufrufen (und das ist die aus der
+eigenen Klasse, nicht die in <i>Transportmittel</i> definierte).
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100%>
+<tr>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top width=1000>
+
+<p>
+Falls es vorkommt, dass die Implementierung in einer bestimmten Klasse
+mit der seiner Basisklasse übereinstimmt, braucht die Methode
+nicht noch einmal überlagert zu werden. Das Laufzeitsystem verwendet
+in diesem Fall die Implementierung aus der Vaterklasse, die der eigenen
+Klasse am nächsten liegt.</td>
+<td><img src="trp1_1.gif" width=2></td>
+<td valign=top>
+<table border=0 cellspacing=0 cellpadding=1 width=100% bgcolor="#000077">
+<tr>
+<td><font color="#FFFFFF"> Hinweis </font></td>
+</tr>
+</table>
+</td>
+<td width=1 align=left valign=top bgcolor="#000077"><img src="trp1_1.gif"></td>
+</tr>
+</table>
+
+
+<!-- Section -->
+<a name="sectlevel3id007001007"></a>
+<h3>7.1.7 Fazit </h3>
+
+<p>
+Objektorientierte Programmierung erlaubt eine natürliche Modellierung
+vieler Problemstellungen. Sie vermindert die Komplexität eines
+Programms durch Abstraktion, Kapselung, definierte Schnittstellen
+und Reduzierung von Querzugriffen. Sie stellt Hilfsmittel zur Darstellung
+von Beziehungen zwischen Klassen und Objekten dar, und sie erhöht
+die Effizienz des Entwicklers durch Förderung der Wiederverwendung
+von Programmcode. Wir werden in den nächsten Abschnitten zeigen,
+wie die objektorientierte Programmierung sich in Java gestaltet.
+<hr>
+<table border=0 cellpadding=0 cellspacing=1 width="100%">
+<tr bgcolor="#EEFFCC">
+<td width="7%" align=center bgcolor="#DDCC99"><a href="cover.html"> Titel </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100003.html"> Inhalt </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="search.html"> Suchen </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="index.html"> Index </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/index.html" onClick="this.href=getDocIndex()"> DOC </a>
+<td align="right">Handbuch der Java-Programmierung, 5. Auflage, Addison
+Wesley, Version 5.0.1
+<tr bgcolor="#EEFFCC">
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100046.html"> << </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100046.html"> < </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100048.html"> > </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100051.html"> >> </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="../jdkdocs/api/index.html" onClick="this.href=getApiIndex()"> API </a>
+<td align="right">© 1998, 2007 Guido Krüger & Thomas
+Stark, <a href="http://www.javabuch.de">http://www.javabuch.de</a>
+</table>
+<a name="endofbody"></a>
+</body>
+</html>
|
