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/k100062.html | |
| download | Studium-33613a85afc4b1481367fbe92a17ee59c240250b.tar.gz Studium-33613a85afc4b1481367fbe92a17ee59c240250b.tar.bz2 | |
Diffstat (limited to 'Master/Reference Architectures and Patterns/hjp5/html/k100062.html')
| -rw-r--r-- | Master/Reference Architectures and Patterns/hjp5/html/k100062.html | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/Master/Reference Architectures and Patterns/hjp5/html/k100062.html b/Master/Reference Architectures and Patterns/hjp5/html/k100062.html new file mode 100644 index 0000000..a3038cf --- /dev/null +++ b/Master/Reference Architectures and Patterns/hjp5/html/k100062.html @@ -0,0 +1,318 @@ +<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,k100057.html;106,k100061.html;107,k100063.html;108,k100064.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="k100057.html"> << </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100061.html"> < </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100063.html"> > </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100064.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 9 - OOP III: Interfaces
+</table>
+<hr>
+
+
+<!-- Section -->
+<a name="sectlevel2id009005"></a>
+<h2>9.5 Interfaces und Hilfsklassen </h2>
+<hr>
+<ul>
+<li><a href="k100062.html#sectlevel2id009005">9.5 Interfaces und Hilfsklassen</a>
+<ul>
+<li><a href="k100062.html#sectlevel3id009005001">9.5.1 Die Default-Implementierung</a>
+<li><a href="k100062.html#sectlevel3id009005002">9.5.2 Delegation an die Default-Implementierung</a>
+<li><a href="k100062.html#sectlevel3id009005003">9.5.3 Die leere Implementierung</a>
+</ul>
+</ul>
+<hr>
+
+<p>
+In den vorigen Abschnitten wurde gezeigt, dass es viele Gemeinsamkeiten
+zwischen (abstrakten) Klassen und Interfaces gibt. Während der
+Designphase eines komplexen Softwaresystems ist es daher häufig
+schwierig, sich für eine von beiden Varianten zu entscheiden.
+Für die Verwendung des Interfaces spricht die größere
+Flexibilität durch die Möglichkeit, in unterschiedlichen
+Klassenhierarchien verwendet zu werden. Für die Verwendung einer
+Klasse spricht die Möglichkeit, bereits ausformulierbare Teile
+der Implementation zu realisieren und die Fähigkeit, statische
+Bestandteile und Konstruktoren unterzubringen.
+
+<p>
+Wir wollen in diesem Abschnitt zeigen, wie sich beide Ansätze
+vereinen lassen. Dabei wird zunächst jeweils ein Interface zur
+Verfügung gestellt und seine Anwendung dann unter Verwendung
+einer Hilfsklasse vereinfacht.
+
+<!-- Section -->
+
+<a name="sectlevel3id009005001"></a>
+<h3>9.5.1 Die Default-Implementierung </h3>
+
+<p>
+Wird ein Interface erstellt, das voraussichtlich häufig implementiert
+werden muss und/oder viele Methoden definiert, ist es sinnvoll, eine
+<a name="ixa100570"><i>Default-Implementierung</i></a> zur Verfügung
+zu stellen. Damit ist eine Basisklasse gemeint, die das Interface
+und alle sinnvoll realisierbaren Methoden implementiert. Besitzt eine
+Klasse, die das Interface implementieren muss, keine andere Vaterklasse,
+so kann sie von der Default-Implementierung abgeleitet werden und
+erbt so bereits einen Teil der sonst manuell zu implementierenden
+Funktionalität.
+
+<p>
+Als Beispiel soll ein Interface <font color="#000077"><tt>SimpleTreeNode</tt></font>
+definiert werden, das zur Konstruktion eines Baums verwendet werden
+kann, dessen Knoten von beliebigem Typ sind und jeweils beliebig viele
+Kinder haben:
+<a name="listingid009016"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#00AA00">/* SimpleTreeNode.java */</font>
+<font color="#555555">002 </font>
+<font color="#555555">003 </font><font color="#0000AA">public</font> <font color="#0000AA">interface</font> SimpleTreeNode
+<font color="#555555">004 </font>{
+<font color="#555555">005 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> addChild(SimpleTreeNode child);
+<font color="#555555">006 </font> <font color="#0000AA">public</font> <font color="#006699">int</font> getChildCnt();
+<font color="#555555">007 </font> <font color="#0000AA">public</font> SimpleTreeNode getChild(<font color="#006699">int</font> pos);
+<font color="#555555">008 </font>}</pre>
+</font>
+</td>
+<td valign=top align=right>
+<a href="../examples/SimpleTreeNode.java"><font color="#000055" size=-1>SimpleTreeNode.java</font></a></td>
+</tr>
+</table>
+<i>
+Listing 9.16: Das SimpleTreeNode-Interface</i></p>
+
+<p>
+Die Default-Implementierung könnte wie folgt realisiert werden:
+<a name="listingid009017"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#00AA00">/* DefaultTreeNode.java */</font>
+<font color="#555555">002 </font>
+<font color="#555555">003 </font><font color="#0000AA">public</font> <font color="#0000AA">class</font> DefaultTreeNode
+<font color="#555555">004 </font><font color="#0000AA">implements</font> SimpleTreeNode
+<font color="#555555">005 </font>{
+<font color="#555555">006 </font> <font color="#0000AA">private</font> <font color="#006699">int</font> CAPACITY;
+<font color="#555555">007 </font> <font color="#0000AA">private</font> String name;
+<font color="#555555">008 </font> <font color="#0000AA">private</font> SimpleTreeNode[] childs;
+<font color="#555555">009 </font> <font color="#0000AA">private</font> <font color="#006699">int</font> childcnt;
+<font color="#555555">010 </font>
+<font color="#555555">011 </font> <font color="#0000AA">public</font> DefaultTreeNode(String name)
+<font color="#555555">012 </font> {
+<font color="#555555">013 </font> <font color="#006699">this</font>.CAPACITY = 5;
+<font color="#555555">014 </font> <font color="#006699">this</font>.name = name;
+<font color="#555555">015 </font> <font color="#006699">this</font>.childs = <font color="#0000AA">new</font> SimpleTreeNode[CAPACITY];
+<font color="#555555">016 </font> <font color="#006699">this</font>.childcnt = 0;
+<font color="#555555">017 </font> }
+<font color="#555555">018 </font>
+<font color="#555555">019 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> addChild(SimpleTreeNode child)
+<font color="#555555">020 </font> {
+<font color="#555555">021 </font> <font color="#0000AA">if</font> (childcnt >= CAPACITY) {
+<font color="#555555">022 </font> CAPACITY *= 2;
+<font color="#555555">023 </font> SimpleTreeNode[] newchilds = <font color="#0000AA">new</font> SimpleTreeNode[CAPACITY];
+<font color="#555555">024 </font> <font color="#0000AA">for</font> (<font color="#006699">int</font> i = 0; i < childcnt; ++i) {
+<font color="#555555">025 </font> newchilds[i] = childs[i];
+<font color="#555555">026 </font> }
+<font color="#555555">027 </font> childs = newchilds;
+<font color="#555555">028 </font> }
+<font color="#555555">029 </font> childs[childcnt++] = child;
+<font color="#555555">030 </font> }
+<font color="#555555">031 </font>
+<font color="#555555">032 </font> <font color="#0000AA">public</font> <font color="#006699">int</font> getChildCnt()
+<font color="#555555">033 </font> {
+<font color="#555555">034 </font> <font color="#0000AA">return</font> childcnt;
+<font color="#555555">035 </font> }
+<font color="#555555">036 </font>
+<font color="#555555">037 </font> <font color="#0000AA">public</font> SimpleTreeNode getChild(<font color="#006699">int</font> pos)
+<font color="#555555">038 </font> {
+<font color="#555555">039 </font> <font color="#0000AA">return</font> childs[pos];
+<font color="#555555">040 </font> }
+<font color="#555555">041 </font>
+<font color="#555555">042 </font> <font color="#0000AA">public</font> String toString()
+<font color="#555555">043 </font> {
+<font color="#555555">044 </font> <font color="#0000AA">return</font> name;
+<font color="#555555">045 </font> }
+<font color="#555555">046 </font>}</pre>
+</font>
+</td>
+<td valign=top align=right>
+<a href="../examples/DefaultTreeNode.java"><font color="#000055" size=-1>DefaultTreeNode.java</font></a></td>
+</tr>
+</table>
+<i>
+Listing 9.17: Default-Implementierung des SimpleTreeNode-Interfaces</i></p>
+<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>
+Der Vorteil ist hier noch nicht sehr offensichtlich, weil die Implementierung
+nicht sehr aufwändig ist. Bei komplexeren Interfaces zahlt es
+sich in der Praxis meistens aus, wenn eine Default-Implementierung
+zur Verfügung gestellt wird. Neben der dadurch erzielten Arbeitsersparnis
+nützt sie auch zur Dokumentation und stellt eine Referenzimplementierung
+des Interfaces dar.</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="sectlevel3id009005002"></a>
+<h3>9.5.2 <a name="ixa100571">Delegation</a> an die Default-Implementierung
+</h3>
+
+<p>
+Läßt sich eine potentielle <font color="#000077"><tt>SimpleTreeNode</tt></font>-Klasse
+nicht von <font color="#000077"><tt>DefaultTreeNode</tt></font> ableiten,
+muss sie das Interface selbst implementieren. Besitzt die Default-Implementierung
+bereits nennenswerte Funktionalitäten, wäre es schlechter
+Stil (und auch sehr fehlerträchtig), diese ein zweites Mal zu
+implementieren. Statt dessen ist es eventuell möglich, die Implementierung
+an die bereits vorhandene <font color="#000077"><tt>DefaultTreeNode</tt></font>
+zu <i>delegieren</i>.
+
+<p>
+Dazu muss die zu implementierende Klasse eine Membervariable vom Typ
+<font color="#000077"><tt>DefaultTreeNode</tt></font> anlegen und
+alle Aufrufe der Interface-Methoden an dieses Objekt weiterleiten.
+Soll beispielsweise die Klasse <font color="#000077"><tt>Auto</tt></font>
+aus <a href="k100048.html#autoklasse">Listing 7.1</a> in eine <font color="#000077"><tt>SimpleTreeNode</tt></font>
+verwandelt werden, könnte die Implementierung durch Delegation
+wie folgt vereinfacht werden:
+<a name="listingid009018"></a>
+
+<p>
+<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#DDDDDD">
+<tr>
+<td valign=top>
+<font color="#000055">
+<pre>
+<font color="#555555">001 </font><font color="#00AA00">/* Auto5.java */</font>
+<font color="#555555">002 </font>
+<font color="#555555">003 </font><font color="#0000AA">public</font> <font color="#0000AA">class</font> Auto5
+<font color="#555555">004 </font><font color="#0000AA">implements</font> SimpleTreeNode
+<font color="#555555">005 </font>{
+<font color="#555555">006 </font> <font color="#0000AA">public</font> String name;
+<font color="#555555">007 </font> <font color="#0000AA">public</font> <font color="#006699">int</font> erstzulassung;
+<font color="#555555">008 </font> <font color="#0000AA">public</font> <font color="#006699">int</font> leistung;
+<font color="#555555">009 </font>
+<font color="#555555">010 </font> <font color="#0000AA">private</font> SimpleTreeNode treenode = <font color="#0000AA">new</font> DefaultTreeNode(<font color="#0000FF">""</font>);
+<font color="#555555">011 </font>
+<font color="#555555">012 </font> <font color="#0000AA">public</font> <font color="#006699">void</font> addChild(SimpleTreeNode child)
+<font color="#555555">013 </font> {
+<font color="#555555">014 </font> treenode.addChild(child);
+<font color="#555555">015 </font> }
+<font color="#555555">016 </font>
+<font color="#555555">017 </font> <font color="#0000AA">public</font> <font color="#006699">int</font> getChildCnt()
+<font color="#555555">018 </font> {
+<font color="#555555">019 </font> <font color="#0000AA">return</font> treenode.getChildCnt();
+<font color="#555555">020 </font> }
+<font color="#555555">021 </font>
+<font color="#555555">022 </font> <font color="#0000AA">public</font> SimpleTreeNode getChild(<font color="#006699">int</font> pos)
+<font color="#555555">023 </font> {
+<font color="#555555">024 </font> <font color="#0000AA">return</font> treenode.getChild(pos);
+<font color="#555555">025 </font> }
+<font color="#555555">026 </font>
+<font color="#555555">027 </font> <font color="#0000AA">public</font> String toString()
+<font color="#555555">028 </font> {
+<font color="#555555">029 </font> <font color="#0000AA">return</font> name;
+<font color="#555555">030 </font> }
+<font color="#555555">031 </font>}</pre>
+</font>
+</td>
+<td valign=top align=right>
+<a href="../examples/Auto5.java"><font color="#000055" size=-1>Auto5.java</font></a></td>
+</tr>
+</table>
+<i>
+Listing 9.18: Implementierung des SimpleTreeNode-Interfaces durch
+Delegation</i></p>
+
+<p>
+Hier nutzt die Klasse <font color="#000077"><tt>Auto5</tt></font>
+die Funktionalitäten der Membervariable <font color="#000077"><tt>DefaultTreeNode</tt></font>
+zur Verwaltung von Unterknoten und leitet alle entsprechenden Methodenaufrufe
+an sie weiter. Die Verwaltung des Knotennamens erfolgt dagegen mit
+Hilfe der eigenen Membervariable <font color="#000077"><tt>name</tt></font>.
+
+
+<!-- Section -->
+<a name="sectlevel3id009005003"></a>
+<h3>9.5.3 Die leere Implementierung </h3>
+
+<p>
+Mitunter wird ein Interface entworfen, bei dem nicht immer alle definierten
+Methoden benötigt werden. In der Java-Klassenbibliothek gibt
+es dafür einige Beispiele, etwa bei Listenern (siehe <a href="k100180.html#kapiteleventhandling">Kapitel 28</a>)
+oder im Collection-API (siehe <a href="k100097.html#kapitelcollections2">Kapitel 15</a>).
+Da bei der Implementierung aber immer alle definierten Methoden implementiert
+werden müssen, wenn die Klasse nicht abstrakt bleiben soll, kann
+es nützlich sein, eine <i>leere</i> Standard-Implementierung
+zur Verfügung zu stellen. Implementierende Klassen können
+sich dann gegebenenfalls von dieser ableiten und brauchen nur noch
+die Methoden zu realisieren, die tatsächlich benötigt werden.
+<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="k100057.html"> << </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100061.html"> < </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100063.html"> > </a>
+<td width="7%" align=center bgcolor="#DDCC99"><a href="k100064.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>
|
