Objekt Polymorphismus
Wir haben Situationen erlebt, in denen Variablen vom Referenztyp andere Typen haben als ihren eigenen. Zum Beispiel sind alle Objekte vom Typ Object
, d.h. jedes gegebene Objekt kann zusätzlich zu seinem eigenen Typ als Object
-Typ-Variable dargestellt werden.
String text = "text";
Object textString = "another string";
String text = "text";
Object textString = text;
In den obigen Beispielen wird eine String-Variable sowohl als String-Typ als auch als Object-Typ dargestellt. Auch wird eine String-Typ-Variable einer Object-Typ-Variable zugewiesen. Eine Zuweisung in die andere Richtung, d.h. die Einstellung einer Object-Typ-Variablen auf einen String-Typ, wird jedoch nicht funktionieren. Das liegt daran, dass Object
-Typ-Variablen nicht vom Typ String
sind.
Object textString = "another string";
String text = textString; // FUNKTIONIERT NICHT!
Worum geht es hier?

Die API-Dokumentation für die String-Klasse beginnt mit einer allgemeinen Überschrift, gefolgt vom Paket der Klasse (java.lang
). Nach den Paketdetails folgt der Name der Klasse (Class String
), gefolgt von der Vererbungshierarchie der Klasse.
java.lang.Objectjava.lang.String
Die Vererbungshierarchie listet alle Klassen auf, die die gegebene Klasse geerbt hat. Geerbte Klassen werden in der Reihenfolge der Vererbung aufgelistet, wobei die zu untersuchende Klasse immer unten steht. In der Vererbungshierarchie der String-Klasse sehen wir, dass die String
-Klasse die Object
-Klasse erbt. In Java kann jede Klasse höchstens eine Klasse erben. Andererseits kann die geerbte Klasse eine andere Klasse geerbt haben. Daher kann eine Klasse indirekt mehr als eine einzige Klasse erben.
Die Vererbungshierarchie kann auch als Liste der verschiedenen Typen betrachtet werden, die die Klasse implementiert.
Das Wissen, dass Objekte viele verschiedene Typen haben können — z.B. vom Typ Object — vereinfacht die Programmierung. Wenn wir in einer Methode nur Methoden benötigen, die in der Klasse Object definiert sind, wie toString
, equals
und hashCode
, können wir einfach Object
als Typ des Methodenparameters verwenden. In diesem Fall können Sie die Methode für jedes Objekt als Parameter übergeben. Schauen wir uns dies anhand der Methode printManyTimes
an. Die Methode erhält eine Variable vom Typ Object
und die Anzahl der Ausgaben als Parameter.
public class Printer {
public void printManyTimes(Object object, int times) {
int i = 0;
while (i < times) {
System.out.println(object.toString());
// oder System.out.println(object);
i = i + 1;
}
}
}
Der Methode kann jedes beliebige Objekt als Parameter übergeben werden. Innerhalb der Methode printManyTimes
hat das Objekt nur Zugriff auf die in der Klasse Object
definierten Methoden, da das Objekt in der Methode als Object
-Typ bekannt ist. Das Objekt kann tatsächlich ein anderer Typ sein.
Printer printer = new Printer();
String string = " o ";
List<String> words = new ArrayList<>();
words.add("polymorphism");
words.add("inheritance");
words.add("encapsulation");
words.add("abstraction");
printer.printManyTimes(string, 2);
printer.printManyTimes(words, 3);
o o [polymorphism, inheritance, encapsulation, abstraction] [polymorphism, inheritance, encapsulation, abstraction] [polymorphism, inheritance, encapsulation, abstraction]
Lassen Sie uns mit der Betrachtung der API-Beschreibung der String
-Klasse fortfahren. Der Vererbungshierarchie in der Beschreibung folgt eine Liste der von der Klasse implementierten Schnittstellen.
All Implemented Interfaces: Serializable, CharSequence, Comparable<String>
Die String
-Klasse implementiert die Schnittstellen Serializable
, CharSequence
und Comparable<String>
. Eine Schnittstelle ist ebenfalls ein Typ. Laut der API-Beschreibung der Klasse können die folgenden Schnittstellen als Typ eines String-Objekts festgelegt werden.
Serializable serializableString = "string";
CharSequence charSequenceString = "string";
Comparable<String> comparableString = "string";
Da wir den Typ des Methodenparameters definieren können, können wir Methoden deklarieren, die ein Objekt erhalten, das eine bestimmte Schnittstelle implementiert. Wenn ein Methodenparameter eine Schnittstelle ist, kann jedes Objekt, das diese Schnittstelle implementiert, als Argument übergeben werden.
Wir erweitern die Klasse Printer
, sodass sie eine Methode zum Ausgeben der Zeichen von Objekten hat, die die CharSequence
-Schnittstelle implementieren. Die CharSequence
-Schnittstelle stellt unter anderem die Methoden int length()
zum Abrufen der Länge eines Strings und char charAt(int index)
zum Abrufen eines Zeichens an einem bestimmten Index bereit.
public class Printer {
public void printManyTimes(Object object, int times) {
int i = 0;
while (i < times) {
System.out.println(object);
i = i + 1;
}
}
public void printCharacters(CharSequence charSequence) {
int i = 0;
while (i < charSequence.length()) {
System.out.println(charSequence.charAt(i));
i = i + 1;
}
}
}
Der Methode printCharacters
kann jedes Objekt übergeben werden, das die CharSequence
-Schnittstelle implementiert. Dazu gehören String
sowie StringBuilder
, die oft funktionaler für den Aufbau von Strings ist als String
. Die Methode printCharacters
gibt jedes Zeichen eines gegebenen Objekts in einer eigenen Zeile aus.
Printer printer = new Printer();
String string = "works";
printer.printCharacters(string);
w o r k s