Das Inklusionsprinzip in Java
Ein Referenztyp enthält Einträge, wie Felder und Methoden. Zur Veranschaulichung sprechen wir hier statt von „Einträgen“ oft von Methoden, weil sie der wichtigste Typ von Einträgen sind.
ℛ Inklusionsprinzip Ein Referenztyp enthält alle nicht-statischen Methoden aller seiner Obertypen. (Inklusionsprinzip)
Das heißt: wenn ein Obertyp eines Typs eine bestimmte nicht-statische Methode enthält, dann muß diese nicht-statische Methode auch in dem Typ selber vorhanden sein. In der Regel hat sie dort auch dieselbe Bedeutung (sie entspricht ihrer Dokumentation im Obertyp).
- Dieser Typ U übernimmt drei Methoden aus dem Typ O und fügt noch zwei eigene hinzu
Typ O,
Obertyp von U
| |
| f() g() h() |
| |
-----|-----------------|--------------
Typ U | f() g() h() | i() j()
--------------------------------------
Beispielsweise ist ein Luxusauto, das um ein Radio und eine Klimaanlage erweitert wurde, weiterhin eine Auto (es kann als Auto verwendet werden).
- Ein Luxusauto übernimmt alle Aspekte eines Autos und fügt noch etwas hinzu
Auto
| |
| Gas Bremse Kupplung |
| |
-----|-------------------------|----------------------
Luxusauto | Gas Bremse Kupplung | Radio Klimaanlage
------------------------------------------------------
Der Begriff „Auto“ ist ein Oberbegriff zu „Luxusauto“, aber ein Auto hat nach dem obigen Diagramm nicht mehr, sondern weniger Möglichkeiten als ein Luxusauto; „Ober-“ bedeutet als nicht „mehr“!
Oft kommt es nur auf die Methoden an, und daher sprechen wir fürderhin der Anschaulichkeit halber oft nur von „Methoden“, wenn eigentlich auch Felder in Frage kommen würden.
Man kann sich die Obertypen auch als Untergliederungen eines Typs vorstellen, dessen Methoden inhaltlich danach zusammengefaßt werden können, ob sie zu einem Obertyp gehören und, wenn ja, zu welchem.
Man kann sich die Obertypen auch als Bausteine eines Typs vorstellen, ein Typ kann aus verschiedene Obertypen „zusammengebaut“ werden, und dann noch um weitere einzelne Methoden erweitert werden.
- Dieser Typ U übernimmt fünf Methoden zweier ihrer Obertypen und fügt noch drei eigene hinzu
Typ O, Typ Q,
Obertyp Obertyp
von U von U
| | | |
| f() g() h() | | i() j() |
| | | |
-----|-----------------|-----|------------|-----------------------
Typ U | f() g() h() | | i() j() | k() l() m()
------------------------------------------------------------------
Ein Typ enthält alle seine Obertypen!
Genauergesagt enthält ein Typ alle Methoden aller seiner Obertypen.
Daher kann man Obertypen auch als Teiltypen ansehen, also als Teile oder Unterteilungen eines Typs.
Untertypen
Ein Untertyp kann verwirrenderweise mehr Methoden als sein Obertyp haben und nicht weniger, obwohl das Präfixoid „Unter-“ als „weniger“ verstanden werden könnte. Wir merken uns dies kurz als:
Ein Untertyp kann mehr Methoden enthalten.
Umgekehrt kann ein Obertyp niemals mehr Methoden enthalten als ein Untertyp.
Das Präfixoid „Unter-“ kommt daher, daß ein Untertyp als ein Spezialfall des Obertyps angesehen werden kann, weil man die zusätzlichen Methoden des Untertyps einfach ignorieren kann, und dann hat man wieder den Obertyp.
Ein Untertyp eines Typs erfüllt alle Erwartungen, die an den Typ gestellt werden.
Obertypen als Gemeinsamkeit mehrerer Typen
Ein Typ kann in mehreren Typen als ein Teiltyp vorkommen. Wenn man den Teiltyp schon kennt, dann muß man ihn nicht noch einmal neu lernen, wenn man ihm in einem anderen Typ wiederbegegnet. Dies ist ein Vorteil der Wiederverwendung von Typen als Obertyp mehrerer anderer Typen.
- Der Typ »O« kommt in zwei Typen als Obertyp vor
Typ O Typ Q
| | | |
| f() g() h() | | i() j() |
| | | |
| | | |
| | | |
-----|-----------------|-----|------------|---------------------
Typ U | f() g() h() | | i() j() | k() l() m()
-----|-----------------|----------------------------------------
| |
| |
| |
| | Typ R
| |
| | | |
| | | p() q() |
| | | |
-----|-----------------|-----|------------|-------------
Typ V | f() g() h() | | p() q() | r()
--------------------------------------------------------
Ein Typ kann „zusammengebaut“ werden, indem verschiedenen schon vorhandene Typen als Teiltypen integriert und eventuell noch weitere einzelne Methoden hinzugefügt werden.
Das folgende Diagramm zeigt einen Typ mit einer Methode »f()«, jeder Typ, der diesen Typ als Obertyp hat, muß dann auch diese Methode enthalten, und kann zusätzlich noch andere Methoden enthalten.
- Typhierarchie
.------------------------------.
| Obertyp von A und B |
|------------------------------|
|------------------------------|
| + f() |
'------------------------------'^
/_\
|
|
.----------------'----------------.
| |
| |.---------------------------. .---------------------------.
| Typ A | | Typ B |
|---------------------------| |---------------------------|
|---------------------------| |---------------------------|
| + f() | | + f() |
| + g() | | + h() |
'---------------------------' '---------------------------'
Das folgende Diagramm zeigt den Typ »java.lang.Number« mit seiner Methode »doubleValue()« als Obertyp der beiden Typen »java.lang.Integer« und »java.lang.Double«, welche diese Methode übernehmen und zusätzlich noch andere Methoden enthalten.
- Typhierarchie
.---------------------------.
| java.lang.Number |
|---------------------------|
|---------------------------|
| + doubleValue() |
'---------------------------'^
/_\
|
|
.----------------'----------------.
| |
| |.---------------------------. .---------------------------.
| java.lang.Integer | | java.lang.Double |
|---------------------------| |---------------------------|
|---------------------------| |---------------------------|
| + doubleValue() | | + doubleValue() |
| + reverse(int) | | + isInfinite() |
'---------------------------' '---------------------------'- Aussprachehinweis
- is infinite ˈɪz ˈɪnfɪnɪt
Beispiel »java.lang.Object«
Der Referenztyp »java.lang.Object« ist Obertyp jedes Referenztyps. Das heißt, daß alle Methoden von »java.lang.Object« in allen Referenztypen, und damit in allen Klassen zu finden sind. Damit sind diese Methoden natürlich besonders wichtig.
Die Klasse »java.lang.Object« hat so viele bekannte Untertypen, daß diese in ihrer Dokumentation nicht aufgelistet werden.
Beispiel Die Klasse »java.lang.Object« ist ein Obertyp der Klasse »java.lang.String«.
Beispiel Die Klasse »java.lang.Object« enthält eine nicht-statische Methode »toString()«, daher ist eine nicht-statische Methode »toString()« auch in allen anderen Referenztypen zu finden.
Beispiel »java.lang.Exception«
Sieht man sich einmal die Dokumentation des Typ »java.lang.Exception« an, so erkennt man, daß dieser aus seinen beiden Obertypen »java.lang.Throwable« und »java.lang.Object« zusammenkopiert ist, ohne daß er noch weitere eigene Einträge hinzufügt.
- Die Methoden des Typs »java.lang.Exception«
- Method Summary
- Methods inherited from class java.lang.Throwable
- addSuppressed, fillInStackTrace, getCause, getLocalizedMessage, getMessage, getStackTrace, getSuppressed, initCause, printStackTrace, printStackTrace, printStackTrace, setStackTrace, toString
- Methods inherited from class java.lang.Object
- clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
Übungsfragen
? »java.lang.CharSequence« und »java.lang.String«
Können Sie eine nicht-statische Methode im Referenztyp »java.lang.CharSequence« finden, die nicht im Referenztyp »java.lang.String« vorhanden ist? Wenn ja, welche?
Können Sie eine nicht-statische Methode im Referenztyp »java.lang.String« finden, die nicht im Referenztyp »java.lang.CharSequence« vorhanden ist? Wenn ja, welche?
Sind die Ergebnisse Ihrer Suche mit dem Inklusionsprinzip verträglich? (Das Inklusionsprinzip lautet: „Ein Referenztyp enthält alle nicht-statischen Methoden aller seiner Obertypen.“)
? Übungsfrage
In welchen der folgenden Referenztypen ist eine nicht-statische Methode »toString()« enthalten?
In welchen der folgenden Referenztypen ist eine nicht-statische Methode »length()« enthalten?
- »java.lang.Object«
- »java.lang.String«
- »java.io.PrintStream«
? Methoden
Angenommen, es könnten nicht-statische Methoden zu Referenztypen hinzugefügt werden. Zu welchem Referenztyp sollte dann eine nicht-statische Methode hinzugefügt werden, damit diese auch in allen anderen Referenztypen enthalten ist?
? Übungsfrage ⃗
Der Typ eines Parameternamens als Ausdruck ist stets so, wie dies durch die Deklaration des Parameternamens festgelegt wurde. Der Typ des Ausdrucks »s« im Rumpf der Methode »m« des folgenden Programms ist also »java.lang.String«, weil dies durch die Parameterdeklaration mit »final java.lang.String s« festgelegt wurde.
Können Sie ohne Ausprobieren vorhersagen, ob das folgende Programm vom Compiler akzeptiert werden wird?
(Bei allen Übungen in diesem Kurs darf die API-Dokumentation gelesen werden.)
Main.java
public final class Main
{public static void m( final java.lang.String string )
{ string.length(); }public static void main( final java.lang.String[] args )
{ }}
? Übungsfrage ⃗
Können Sie ohne Ausprobieren vorhersagen, ob das folgende Programm vom Compiler akzeptiert werden wird?
Main.java
public final class Main
{public static void m( final java.lang.CharSequence sequence )
{ sequence.isEmpty(); }public static void main( final java.lang.String[] args )
{ }}
? Übungsfrage ⃗
Können Sie ohne Ausprobieren vorhersagen, ob das folgende Programm vom Compiler akzeptiert werden wird?
Main.java
public final class Main
{public static void m( final java.lang.CharSequence sequence )
{ sequence.length(); }public static void main( final java.lang.String[] args )
{ }}
? Übungsfrage ⃗
Können Sie ohne Ausprobieren vorhersagen, ob das folgende Programm vom Compiler akzeptiert werden wird?
Main.java
public final class Main
{public static void m( final java.lang.String string )
{ string.isEmpty(); }public static void main( final java.lang.String[] args )
{ }}