Skip to main content

Die Java Klassenhierarchie

Java ist eine objektorientierte Programmiersprache. Mit Ausnahme der primitiven Datentypen, ist alle Funktionalität, die uns Java zur Verfügung stellt, in Klassen organisiert. Java stellt uns tausende von fertigen Klassen zur Verfügung, die wir für die Entwicklung von Programmen nutzen können. Diese Klassen sind alle in einer Klassenhierarchie angeordnet.

Nachfolgend sehen wir einen Ausschnitt aus der Dokumentation von Java, in der die Hierarchie dargestellt ist.

Wir sehen, dass zuoberst in der Hierarchie die Klasse Object steht. Die Klasse Object definiert grundlegende Methode, die für alle Klassen in Java zur Verfügung stehen. Dies ist zum Beispiel die Methode toString, welche es erlaubt jedes Objekt in eine Textrepräsentation umzuwandeln. Oder die Methode equals, welche bestimmt, ob zwei Objekte gleich sind. Damit diese Methoden sich für eine selbstdefinierte Klasse sinnvoll verhalten, müssen diese dann von jeder Klasse eigens definiert werden.

Interessant ist auch die Klasse Number. Wir sehen, dass die Wrapper-Klassen Integer, Double, etc. alle von Number erben.

Object als implizite Superklasse jeder Klasse

Dass jede Klasse in der Java Klassenhierarchie von Object erbt, ist kein Zufall. Dies wird von Java so forciert. Wenn immer wir eine eigene Klasse schreiben, definiert Java implizit, dass die Klasse von Object erbt. Die folgenden zwei Klassendefinitionen sind also äquivalent:

class AClass extends Object {}

und

class AClass {}

Damit ist sichergestellt, dass die in Object definierten Methoden, in jedem Objekt, unabhängig von dessem Typ, zur Verfügung steht. Zum Beispiel verfügt über diesen Mechanismus jede Klasse über die Methoden equals, mit der das Objekt verglichen werden kann.

Downcasting

Wir haben bereits gesehen, dass wir ein Objekt eines bestimmten Typs jeweils einer Variable vom Typ oben in der Hierarchie zuweisen können. Wir können also jedes Objekt einer Variable vom Typ Object zuweisen.

Object anInteger = new Integer(5);
Object aString = new String("Hello world");

Umgekehrt funktioniert dies aber nicht. Wir können die Variable anInteger, die den Typ Object hat, nicht wieder einer Variablen vom Typ Integer zuweisen. Dies obwohl im Moment darin eine Instanz vom Typ Integer gespeichert ist. Das folgende würde also nicht Funktionieren

Object anInteger = new Integer(5);
Integer theSameInterger = anInteger; // Fehler

Der Grund dafür ist, dass Java nicht garantieren kann, dass in der Variable anInteger ein Integer gespeichert ist. Es könnte ein Objekt beliebigen Typs sein. Wir können Java aber zwingen, dies zu akzeptieren, indem wir einen Cast ausführen. Dazu schreiben wir den Subtyp in Klammern links neben den Wert:

Object anInteger = new Integer(5);
Integer theSameInterger = (Integer) anInteger; // Dies ist gültig

In diesem Fall ist es die Verantwortung des Programmierenden, sicherzustellen, dass der Wert wirklich vom richtigen Typ ist. Stimmt der Typ der im Cast angegeben wird nicht mit dem Typ des Objekts überein, kommt es zu einem Laufzeitfehler, und das Programm bricht ab. Um sicher zu gehen, dass es sich wirklich um ein Objekt vom richtigen Typ handelt, können wir die spezielle Anweisung instanceof nutzen. anInteger instanceof Integer würde den Wert true ergeben, aber aString instanceof Integer würde den Wert false ergeben.

Experimente

  • Was passiert, wenn Sie den Cast weglassen?
  • Was passiert, wenn Sie versuchen einen String zu einem Integer zu casten?
  • Probieren Sie das Kommando instanceof aus.

Haben Sie Fragen oder Bemerkungen? Schreiben Sie diese doch ins Forum.