1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
|
<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,k100051.html;106,k100051.html;107,k100053.html;108,k100057.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="k100051.html"> << </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100051.html"> < </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100053.html"> > </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100057.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 8 - OOP II: Vererbung, Polymorphismus und statische Elemente
</table>
<hr>
<!-- Section -->
<a name="sectlevel2id008001"></a>
<h2>8.1 <a name="ixa100490">Vererbung</a></h2>
<hr>
<ul>
<li><a href="k100052.html#sectlevel2id008001">8.1 Vererbung</a>
<ul>
<li><a href="k100052.html#sectlevel3id008001001">8.1.1 Ableiten einer Klasse</a>
<li><a href="k100052.html#klasseobject">8.1.2 Die Klasse Object</a>
<li><a href="k100052.html#sectlevel3id008001003">8.1.3 Überlagern von Methoden</a>
<ul>
<li><a href="k100052.html#sectlevel4id008001003001">Dynamische Methodensuche</a>
<li><a href="k100052.html#sectlevel4id008001003002">Aufrufen einer verdeckten Methode</a>
</ul>
<li><a href="k100052.html#vererbungvonkonstruktoren">8.1.4 Vererbung von Konstruktoren</a>
<ul>
<li><a href="k100052.html#sectlevel4id008001004001">Konstruktorenverkettung</a>
<li><a href="k100052.html#sectlevel4id008001004002">Der Default-Konstruktor</a>
<li><a href="k100052.html#sectlevel4id008001004003">Überlagerte Konstruktoren</a>
<li><a href="k100052.html#sectlevel4id008001004004">Destruktorenverkettung</a>
</ul>
</ul>
</ul>
<hr>
<p>
Eines der wesentlichen Designmerkmale objektorientierter Sprachen
ist die Möglichkeit, Variablen und Methoden zu Klassen zusammenzufassen.
Ein weiteres wichtiges Merkmal ist das der <i>Vererbung</i>, also
der Möglichkeit, Eigenschaften vorhandener Klassen auf neue Klassen
zu übertragen. Fehlt diese Fähigkeit, bezeichnet man die
Sprache auch als lediglich <i>objektbasiert</i>.
<p>
Man unterscheidet dabei zwischen <a name="ixa100491"><i>einfacher Vererbung</i></a>,
bei der eine Klasse von maximal einer anderen Klasse abgeleitet werden
kann, und <a name="ixa100492"><i>Mehrfachvererbung</i></a>, bei der
eine Klasse von mehr als einer anderen Klasse abgeleitet werden kann.
In Java gibt es lediglich Einfachvererbung, um den Problemen aus dem
Weg zu gehen, die durch Mehrfachvererbung entstehen können. Um
die Einschränkungen in den Designmöglichkeiten, die bei
Einfachvererbung entstehen, zu vermeiden, wurde mit Hilfe der <a name="ixa100493"><i>Interfaces</i></a>
eine neue, restriktive Art der Mehrfachvererbung eingeführt.
Wir werden später darauf zurückkommen.
<!-- Section -->
<a name="sectlevel3id008001001"></a>
<h3>8.1.1 <a name="ixa100494">Ableiten einer Klasse</a></h3>
<p>
Um eine neue Klasse aus einer bestehenden abzuleiten, ist im Kopf
der Klasse mit Hilfe des Schlüsselworts <a name="ixa100495"><a href="index_e.html#ixb100416"><font color=#000080><tt>extends</tt></font></a></a>
ein Verweis auf die Basisklasse anzugeben. Hierdurch erbt die abgeleitete
Klasse alle Eigenschaften der Basisklasse, d.h. alle Variablen und
alle Methoden. Durch Hinzufügen neuer Elemente oder Überladen
der vorhandenen kann die Funktionalität der abgeleiteten Klasse
erweitert werden.
<p>
Als Beispiel wollen wir eine neue Klasse <font color="#000077"><tt>Cabrio</tt></font>
definieren, die sich von <font color="#000077"><tt>Auto</tt></font>
nur dadurch unterscheidet, dass sie zusätzlich die Zeit, die
zum Öffnen des Verdecks benötigt wird, speichern soll:
<a name="listingid008001"></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="#0000AA">class</font> Cabrio
<font color="#555555">002 </font><font color="#0000AA">extends</font> Auto
<font color="#555555">003 </font>{
<font color="#555555">004 </font> <font color="#006699">int</font> vdauer;
<font color="#555555">005 </font>}</pre>
</font>
</td>
</tr>
</table>
<i>
Listing 8.1: Ein einfaches Beispiel für Vererbung</i></p>
<p>
Wir können nun nicht nur auf die neue Variable <font color="#000077"><tt>vdauer</tt></font>,
sondern auch auf alle Elemente der Basisklasse <font color="#000077"><tt>Auto</tt></font>
zugreifen:
<a name="listingid008002"></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>Cabrio kfz1 = <font color="#0000AA">new</font> Cabrio();
<font color="#555555">002 </font>kfz1.name = <font color="#0000FF">"MX5"</font>;
<font color="#555555">003 </font>kfz1.erstzulassung = 1994;
<font color="#555555">004 </font>kfz1.leistung = 115;
<font color="#555555">005 </font>kfz1.vdauer = 120;
<font color="#555555">006 </font>System.out.println(<font color="#0000FF">"Alter = "</font>+kfz1.alter());</pre>
</font>
</td>
</tr>
</table>
<i>
Listing 8.2: Zugriff auf geerbte Membervariablen</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>
Die Vererbung von Klassen kann beliebig tief geschachtelt werden.
Eine abgeleitete Klasse erbt dabei jeweils die Eigenschaften der unmittelbaren
Vaterklasse, die ihrerseits die Eigenschaften ihrer unmittelbaren
Vaterklasse erbt usw. Wir können also beispielsweise die Klasse
<font color="#000077"><tt>Cabrio</tt></font> verwenden, um daraus
eine neue Klasse <font color="#000077"><tt>ZweisitzerCabrio</tt></font>
abzuleiten:</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>
<a name="listingid008003"></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="#0000AA">class</font> ZweisitzerCabrio
<font color="#555555">002 </font><font color="#0000AA">extends</font> Cabrio
<font color="#555555">003 </font>{
<font color="#555555">004 </font> <font color="#006699">boolean</font> notsitze;
<font color="#555555">005 </font>}</pre>
</font>
</td>
</tr>
</table>
<i>
Listing 8.3: Ableitung einer abgeleiteten Klasse</i></p>
<p>
Diese könnte nun verwendet werden, um ein Objekt zu instanzieren,
das die Eigenschaften der Klassen <font color="#000077"><tt>Auto</tt></font>,
<font color="#000077"><tt>Cabrio</tt></font> und <font color="#000077"><tt>ZweisitzerCabrio</tt></font>
hat:
<a name="listingid008004"></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>ZweisitzerCabrio kfz1 = <font color="#0000AA">new</font> ZweisitzerCabrio();
<font color="#555555">002 </font>kfz1.name = <font color="#0000FF">"911-T"</font>;
<font color="#555555">003 </font>kfz1.erstzulassung = 1982;
<font color="#555555">004 </font>kfz1.leistung = 94;
<font color="#555555">005 </font>kfz1.vdauer = 50;
<font color="#555555">006 </font>kfz1.notsitze = <font color="#006699">true</font>;
<font color="#555555">007 </font>System.out.println(<font color="#0000FF">"Alter = "</font>+kfz1.alter());</pre>
</font>
</td>
</tr>
</table>
<i>
Listing 8.4: Zugriff auf mehrfach vererbte Membervariablen</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>
Nicht jede Klasse darf zur Ableitung neuer Klassen verwendet werden.
Besitzt eine Klasse das Attribut <a name="ixa100496"><a href="index_f.html#ixb100401"><font color=#000080><tt>final</tt></font></a></a>,
ist es nicht erlaubt, eine neue Klasse aus ihr abzuleiten. Die möglichen
Attribute einer Klasse werden im nächsten Abschnitt erläutert.</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="klasseobject"></a>
<h3>8.1.2 Die Klasse <a name="ixa100497">Object</a> </h3>
<p>
Enthält eine Klasse keine <a href="index_e.html#ixb100416"><font color=#000080><tt>extends</tt></font></a>-Klausel,
so besitzt sie die implizite Vaterklasse <a name="ixa100498"><a href="index_o.html#ixb100224"><font color=#000080><tt>Object</tt></font></a></a>.
Jede Klasse, die keine <a href="index_e.html#ixb100416"><font color=#000080><tt>extends</tt></font></a>-Klausel
besitzt, wird direkt aus <a href="index_o.html#ixb100224"><font color=#000080><tt>Object</tt></font></a>
abgeleitet. Jede explizit abgeleitete Klasse stammt am oberen Ende
ihrer Vererbungslinie von einer Klasse ohne explizite Vaterklasse
ab und ist damit ebenfalls aus <a href="index_o.html#ixb100224"><font color=#000080><tt>Object</tt></font></a>
abgeleitet. <a href="index_o.html#ixb100224"><font color=#000080><tt>Object</tt></font></a>
ist also die Superklasse aller anderen Klassen.
<p>
Die Klasse <a href="index_o.html#ixb100224"><font color=#000080><tt>Object</tt></font></a>
definiert einige elementare Methoden, die für alle Arten von
Objekten nützlich sind:
<p>
<table border=0 cellspacing=0 cellpadding=0 width=100% bgcolor="#EEFFCC">
<tr>
<td valign=top width=100%>
<font color="#660066">
<pre>
boolean equals(Object obj)
protected Object clone()
String toString()
int hashCode()
</pre>
</font>
</td>
<td valign=top>
<a href="../jdkdocs/api/java/lang/Object.html" onClick="this.href=getApiDoc('java.lang.Object')"><font color="#660066" size=-1>java.lang.Object</font></a></td>
</tr>
</table>
<p>
Die Methode <a name="ixa100499"><a href="index_e.html#ixb100223"><font color=#000080><tt>equals</tt></font></a></a>
testet, ob zwei Objekte denselben Inhalt haben, <a name="ixa100500"><a href="index_c.html#ixb100278"><font color=#000080><tt>clone</tt></font></a></a>
kopiert ein Objekt, <a name="ixa100501"><a href="index_t.html#ixb100327"><font color=#000080><tt>toString</tt></font></a></a>
erzeugt eine <a href="index_s.html#ixb100117"><font color=#000080><tt>String</tt></font></a>-Repräsentation
des Objekts, und <a name="ixa100502"><a href="index_h.html#ixb100418"><font color=#000080><tt>hashCode</tt></font></a></a>
berechnet einen numerischen Wert, der als Schlüssel zur Speicherung
eines Objekts in einer <a href="index_h.html#ixb100419"><font color=#000080><tt>Hashtable</tt></font></a>
verwendet werden kann. Damit diese Methoden in abgeleiteten Klassen
vernünftig funktionieren, müssen sie bei Bedarf überlagert
werden. Für <a href="index_e.html#ixb100223"><font color=#000080><tt>equals</tt></font></a>
und <a href="index_c.html#ixb100278"><font color=#000080><tt>clone</tt></font></a>
gilt das insbesondere, wenn das Objekt Referenzen enthält.
<!-- Section -->
<a name="sectlevel3id008001003"></a>
<h3>8.1.3 <a name="ixa100503">Überlagern von Methoden</a><a name="ixa100504"></a></h3>
<p>
Neben den Membervariablen erbt eine abgeleitete Klasse auch die Methoden
ihrer Vaterklasse (wenn dies nicht durch spezielle Attribute verhindert
wird). Daneben dürfen auch neue Methoden definiert werden. Die
Klasse besitzt dann alle Methoden, die aus der Vaterklasse geerbt
wurden, und zusätzlich die, die sie selbst neu definiert hat.
<p>
Daneben dürfen auch bereits von der Vaterklasse geerbte Methoden
neu definiert werden. In diesem Fall spricht man von <i>Überlagerung</i>
der Methode. Wurde eine Methode überlagert, wird beim Aufruf
der Methode auf Objekten dieses Typs immer die überlagernde Version
verwendet.
<p>
Das folgende Beispiel erweitert die Klasse <font color="#000077"><tt>ZweisitzerCabrio</tt></font>
um die Methode <font color="#000077"><tt>alter</tt></font>, das nun
in Monaten ausgegeben werden soll:
<a name="listingid008005"></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="#0000AA">class</font> ZweisitzerCabrio
<font color="#555555">002 </font><font color="#0000AA">extends</font> Cabrio
<font color="#555555">003 </font>{
<font color="#555555">004 </font> <font color="#006699">boolean</font> notsitze;
<font color="#555555">005 </font>
<font color="#555555">006 </font> <font color="#0000AA">public</font> <font color="#006699">int</font> alter()
<font color="#555555">007 </font> {
<font color="#555555">008 </font> <font color="#0000AA">return</font> 12 * (2000 - erstzulassung);
<font color="#555555">009 </font> }
<font color="#555555">010 </font>}</pre>
</font>
</td>
</tr>
</table>
<i>
Listing 8.5: Überlagern einer Methode in einer abgeleiteten Klasse</i></p>
<p>
Da die Methode <font color="#000077"><tt>alter</tt></font> bereits
aus der Klasse <font color="#000077"><tt>Cabrio</tt></font> geerbt
wurde, die sie ihrerseits von <font color="#000077"><tt>Auto</tt></font>
geerbt hat, handelt es sich um eine <i>Überlagerung</i>. Zukünftig
würde dadurch in allen Objekten vom Typ <font color="#000077"><tt>ZweisitzerCabrio</tt></font>
bei Aufruf von <font color="#000077"><tt>alter</tt></font> die überlagernde
Version, bei allen Objekten des Typs <font color="#000077"><tt>Auto</tt></font>
oder <font color="#000077"><tt>Cabrio</tt></font> aber die ursprüngliche
Version verwendet werden. Es wird immer die Variante aufgerufen, die
dem aktuellen Objekt beim Zurückverfolgen der Vererbungslinie
am nächsten liegt.
<!-- Section -->
<a name="sectlevel4id008001003001"></a>
<h4><a name="ixa100505">Dynamische Methodensuche</a></h4>
<p>
Nicht immer kann bereits der Compiler entscheiden, welche Variante
einer überlagerten Methode er aufrufen soll. In <a href="k100028.html#abschnitttypkonvertierungen">Abschnitt 4.6</a>
und <a href="k100047.html#polymorphismus">Abschnitt 7.1.6</a> wurde
bereits erwähnt, dass das Objekt einer abgeleiteten Klasse zuweisungskompatibel
zu der Variablen einer übergeordneten Klasse ist. Wir dürfen
also beispielsweise ein <font color="#000077"><tt>Cabrio</tt></font>-Objekt
ohne weiteres einer Variablen vom Typ <font color="#000077"><tt>Auto</tt></font>
zuweisen.
<p>
Die Variable vom Typ <font color="#000077"><tt>Auto</tt></font> kann
während ihrer Lebensdauer also Objekte verschiedenen Typs enthalten
(insbesondere solche vom Typ <font color="#000077"><tt>Auto</tt></font>,
<font color="#000077"><tt>Cabrio</tt></font> und <font color="#000077"><tt>ZweisitzerCabrio</tt></font>).
Damit kann natürlich nicht schon zur Compile-Zeit entschieden
werden, welche Version einer überlagerten Methode aufgerufen
werden soll. Erst während das Programm läuft, ergibt sich,
welcher Typ von Objekt zu einem bestimmten Zeitpunkt in der Variable
gespeichert wird. Der Compiler muss also Code generieren, um dies
zur Laufzeit zu entscheiden. Man bezeichnet dies auch als <a name="ixa100506"><i>dynamisches
Binden</i></a>.
<p>
In C++ wird dieses Verhalten durch virtuelle Funktionen realisiert
und muss mit Hilfe des Schlüsselworts <font color="#000077"><tt>virtual</tt></font>
explizit angeordnet werden. In Java ist eine explizite Deklaration
nicht nötig, denn Methodenaufrufe werden immer dynamisch interpretiert.
Der dadurch verursachte Overhead ist allerdings nicht zu vernachlässigen
und liegt deutlich über den Kosten eines statischen Methodenaufrufs.
Um das Problem zu umgehen, gibt es mehrere Möglichkeiten, dafür
zu sorgen, dass eine Methode nicht dynamisch interpretiert wird. Dabei
wird mit Hilfe zusätzlicher Attribute dafür gesorgt, dass
die betreffende Methode nicht überlagert werden kann:
<ul>
<li>Methoden vom Typ <a name="ixa100507"><a href="index_p.html#ixb100085"><font color=#000080><tt>private</tt></font></a></a>
sind in abgeleiteten Klassen nicht sichtbar und können daher
nicht überlagert werden.
<li>Bei Methoden vom Typ <a name="ixa100508"><a href="index_f.html#ixb100401"><font color=#000080><tt>final</tt></font></a></a>
deklariert der Anwender explizit, dass sie nicht überlagert werden
sollen.
<li>Auch bei <a name="ixa100509"><a href="index_s.html#ixb100422"><font color=#000080><tt>static</tt></font></a></a>-Methoden,
die ja unabhängig von einer Instanz existieren, besteht das Problem
nicht.
</ul>
<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 <a href="k100055.html#abstraktpolymorph">Abschnitt 8.4</a> werden
wir das Thema <i>Polymorphismus</i> noch einmal aufgreifen und ein
ausführliches Beispiel für dynamische Methodensuche geben.</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="sectlevel4id008001003002"></a>
<h4>Aufrufen einer verdeckten Methode </h4>
<p>
Wird eine Methode <font color="#000077"><tt>x</tt></font> in einer
abgeleiteten Klasse überlagert, wird die ursprüngliche Methode
<font color="#000077"><tt>x</tt></font> verdeckt. Aufrufe von <font color="#000077"><tt>x</tt></font>
beziehen sich immer auf die überlagernde Variante. Oftmals ist
es allerdings nützlich, die verdeckte Superklassenmethode aufrufen
zu können, beispielsweise, wenn deren Funktionalität nur
leicht verändert werden soll. In diesem Fall kann mit Hilfe des
Ausdrucks <font color="#000077"><tt>super.x()</tt></font><a name="ixa100510"></a>
die Methode der Vaterklasse aufgerufen werden. Der kaskadierte Aufruf
von Superklassenmethoden (wie in <font color="#000077"><tt>super.super.x()</tt></font>)
ist nicht erlaubt.
<!-- Section -->
<a name="vererbungvonkonstruktoren"></a>
<h3>8.1.4 Vererbung von Konstruktoren </h3>
<!-- Section -->
<a name="sectlevel4id008001004001"></a>
<h4><a name="ixa100511">Konstruktorenverkettung</a></h4>
<p>
Wenn eine Klasse instanziert wird, garantiert Java, dass ein zur Parametrisierung
des <a href="index_n.html#ixb100089"><font color=#000080><tt>new</tt></font></a>-Operators
passender Konstruktor aufgerufen wird. Daneben garantiert der Compiler,
dass auch der Konstruktor der Vaterklasse aufgerufen wird. Dieser
Aufruf kann entweder explizit oder implizit geschehen.
<p>
Falls als erste Anweisung innerhalb eines Konstruktors ein Aufruf
der Methode <a name="ixa100512"><a href="index_s.html#ixb100424"><font color=#000080><tt>super</tt></font></a></a>
steht, wird dies als Aufruf des <a name="ixa100513">Superklassenkonstruktors</a>
interpretiert. <a href="index_s.html#ixb100424"><font color=#000080><tt>super</tt></font></a>
wird wie eine normale Methode verwendet und kann mit oder ohne Parameter
aufgerufen werden. Der Aufruf muss natürlich zu einem in der
Superklasse definierten Konstruktor passen.
<p>
Falls als erste Anweisung im Konstruktor kein Aufruf von <a href="index_s.html#ixb100424"><font color=#000080><tt>super</tt></font></a>
steht, setzt der Compiler an dieser Stelle einen impliziten Aufruf
<font color="#000077"><tt>super();</tt></font> ein und ruft damit
den parameterlosen Konstruktor der Vaterklasse auf. Falls ein solcher
Konstruktor in der Vaterklasse nicht definiert wurde, gibt es einen
Compiler-Fehler. Das ist genau dann der Fall, wenn in der Superklassendeklaration
lediglich <i>parametrisierte</i> Konstruktoren angegeben wurden und
daher ein parameterloser <i>default</i>-Konstruktor nicht automatisch
erzeugt wurde.
<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>
Alternativ zu diesen beiden Varianten, einen Superklassenkonstruktor
aufzurufen, ist es auch erlaubt, mit Hilfe der <a name="ixa100514"><a href="index_t.html#ixb100273"><font color=#000080><tt>this</tt></font></a></a>-Methode
einen anderen Konstruktor der eigenen Klasse aufzurufen. Um die oben
erwähnten Zusagen einzuhalten, muss dieser allerdings selbst
direkt oder indirekt schließlich einen Superklassenkonstruktor
aufrufen.</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="sectlevel4id008001004002"></a>
<h4>Der <a name="ixa100515">Default-Konstruktor</a> </h4>
<p>
Das Anlegen von Konstruktoren in einer Klasse ist optional. Falls
in einer Klasse überhaupt kein Konstruktor definiert wurde, erzeugt
der Compiler beim Übersetzen der Klasse automatisch einen parameterlosen
<i>default</i>-Konstruktor. Dieser enthält lediglich einen Aufruf
des parameterlosen Superklassenkonstruktors.
<!-- Section -->
<a name="sectlevel4id008001004003"></a>
<h4>Überlagerte Konstruktoren </h4>
<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>
Konstruktoren werden nicht vererbt. Alle Konstruktoren, die in einer
abgeleiteten Klasse benötigt werden, müssen neu definiert
werden, selbst wenn sie nur aus einem Aufruf des Superklassenkonstruktors
bestehen.</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>
Durch diese Regel wird bei jedem Neuanlegen eines Objekts eine ganze
Kette von Konstruktoren aufgerufen. Da nach den obigen Regeln jeder
Konstruktor zuerst den Superklassenkonstruktor aufruft, wird die Initialisierung
von oben nach unten in der Vererbungshierarchie durchgeführt:
zuerst wird der Konstruktor der Klasse <a href="index_o.html#ixb100224"><font color=#000080><tt>Object</tt></font></a>
ausgeführt, dann der der ersten Unterklasse usw., bis zuletzt
der Konstruktor der zu instanzierenden Klasse ausgeführt wird.
<!-- Section -->
<a name="sectlevel4id008001004004"></a>
<h4>Destruktorenverkettung </h4>
<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>
Im Gegensatz zu den Konstruktoren werden die Destruktoren eines Ableitungszweiges
nicht automatisch verkettet. Falls eine Destruktorenverkettung erforderlich
ist, kann sie durch explizite Aufrufe des Superklassendestruktors
mit Hilfe der Anweisung <font color="#000077"><tt>super.finalize()</tt></font>
durchgeführt werden.</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>
<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="k100051.html"> << </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100051.html"> < </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100053.html"> > </a>
<td width="7%" align=center bgcolor="#DDCC99"><a href="k100057.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>
|