04.02 Objekte

Beginnen wir Ihre Reise in die Welt der OOP mit einer Einführung in die Objekte. Ein Objekt ist eine Instanz einer Klasse, das Ergebnis eines Bauplans. Sie wissen z. B. wie ein Motor aufgebaut ist? Dann kennen Sie die Klasse. Wenn Sie jetzt diesen Motor bauen, dann haben Sie ein Objekt dieser Klasse erstellt. Bauen Sie einen weiteren Motor nach diesem Bauplan, aber diesmal mit mehr PS, haben Sie ein weiteres Objekt der Motor-Klasse erstellt. Beide Objekte existieren also parallel und vollkommen unabhängig zueinander. Auch wenn beide Objekte von der selben Klasse stammen, können diese selbstverständlich unabhängig voneinander verändert, verwendet und zerstört werden.

Sie fragen sich jetzt bestimmt, warum Sie hier eine Erklärung von Objekten vor sich sehen, obwohl Sie noch gar nicht wissen, was überhaupt eine Klasse ist!? Diese Frage ist durchaus berechtigt und natürlich bekommen Sie eine Antwort darauf: Wie Sie schon richtig erkannt haben, benötigen Sie eine Klasse um ein Objekt davon zu erzeugen. Aber Klassen sind nicht immer etwas reelles und spezifisches wie ein Motor. Klassen repräsentieren auch ganz andere Dinge. Wie z. B. eine Schnittstelle um Dateien zu manipulieren, die Möglichkeit ein Fenster auf dem Bildschirm anzuzeigen, oder Funktionen zur Netzwerkkommunikation mit entfernten Rechnern. Solche Klassen müssen Sie natürlich meistens nicht selbst programmieren, sondern werden direkt vom JDK oder anderen Frameworks bereitgestellt. Dadurch ist es für Sie möglich, sich auf den Kern Ihres Programms zu beschränken, ohne ständig das Rad neu erfinden zu müssen. Deshalb zeigt Ihnen dieses Kapitel lediglich, wie Objekte verwendet werden, und bringt Ihnen ein bisschen Theorie zu selbigen näher.

Ein neues Objekt anlegen

Wie Sie bereits in Kapitel 02.02 Variablen Deklaration gelernt haben, werden neue Objekte von Klassen mithilfe des Schlüsselworts new angelegt. Dabei wird ganz ähnlich vorgegangen, wie bei der Deklaration und Initialisierung von primitiven Datentypen. Zuerst wird der gewünschte Klassennamen genannt. Anschließend der Variablennamen und ein Gleichheitszeichen. Nun kommt new zum Einsatz, gefolgt vom Klassennamen, dem Konstruktor und natürlich wieder dem abschließenden Semikolon. Als Beispiel verwenden wir die Klasse StringBuffer. Diese Klasse ist eine Art Erweiterung für die String-Klasse.

StringBuffer buffer = new StringBuffer();

Bis jetzt sollte alles für Sie klar sein – bis auf den Konstruktor. In diesem Fall wird der Konstruktor durch die beiden Klammern dargestellt. Hierbei handelt es sich um einen leeren Standard-Konstruktor. Jede Klasse kann einen oder mehrere Konstruktoren definieren. Durch Konstruktoren ist es möglich der Klasse bei der Initialisierung des Objekts Parameter in Form von primitiven Datentypen oder anderen Objekten mitzugeben. Dies ist immer dann sinnvoll, wenn die Klasse für weitere Bearbeitungen zwingend entsprechende Daten benötigt. Ein Beispiel wäre die Klasse FileWriter. Wie der Name vermuten lässt, ermöglicht diese Klasse das Schreiben von Daten in eine Datei. FileWriter benötigt natürlich eine Zieldatei, die auch gleich im Konstruktor übergeben wird. Parameter sind in einem Konstruktor auch nützlich, um dem Nutzer der Klasse die direkte Übergabe von optionalen Werten zu ermöglichen. In einem solchen Fall sollten aber mehrere Konstruktoren angeboten werden – einmal mit und einmal ohne die optionalen Parameter.
Mehr dazu finden Sie im Kapitel 04.03.08 Konstruktoren.

null

Ebenso wie primitive Datentypen, haben auch Objekte einen Standardwert (siehe Kapitel 02.03 Primitive Datentypen): null. Dieses Schlüsselwort bedeutet, dass ein Objekt leer ist, also keinen Inhalt hat. Ist dies der Fall, existiert kein Objekt dieser Klasse in dieser Variablen – wohl aber die Variable. Deshalb wird auch jeder Zugriff auf ein null-Objekt mit einer Fehlermeldung (siehe 05.03 NullPointerException) quittiert. Sie können einer Variablen eines Objekts auch selbst den Wert null zuweisen.

Object obj = new Object();
Object obj2 = null;
Object obj3;
obj = null;
obj3 = null;

Dies ist z. B. dann sinnvoll, wenn man den variable might not have been initialized-Compiler-Fehler umgehen will (siehe 05.04 variable might not have been initialized). Natürlich kann dann ein neues Objekt zu einem späteren Zeitpunkt erstellt werden.

Object obj = null;
...
obj = new Object();

Möchten Sie testen, ob eine Objektvariable gleich null ist, können Sie dies mit dem doppelten Gleichheitszeichen bewerkstelligen:

if (obj == null) {
  obj = new Object();
}

Die Klasse finden

Wie Sie zu Beginn dieses Buches gelesen haben, sollten für Java-Klassen Packages verwendet werden, um eine gewisse Ordnerstruktur zwecks logischer und physischer Trennung der einzelnen Klassen zu erreichen. Dadurch ist es ebenfalls möglich zwei Klassen identisch zu benennen, wenn beide Klassen in unterschiedlichen Packages liegen. Deshalb ist es notwendig solche Klassen über ihren vollen Namen inkl. Package anzusprechen.

java.io.File f = new java.io.File(".");

In oberen Beispiel wird ein Objekt der Klasse File, welche sich im Sub-Package io des Packages java befindet, erstellt.

Natürlich müssen Sie – sofern Sie nicht in einer Klasse mehrere Klassen mit selben Namen aus unterschiedlichen Packages verwenden – nicht immer das Package mit angeben. Es genügt, wenn Sie die benötigte Klasse importieren. Dazu erstellen Sie die Import-Anweisung wie folgt zwischen der Angabe des packages und dem Kopf der Klasse in Ihrer Java-Datei:

package de.test;
import java.io.File;
public class ImportTest {

  public static void main(String[] args) {
    File f = new File(".");
  }
}

Sollten Sie viele Klassen aus einem Package verwenden, können Sie auch einfach das komplette Package importieren. Achtung! Sub-Packages werden auch durch dieses Verfahren nicht mit importiert, sondern müssen gesondert importiert werden.

package de.test;
// komplettes package importiert
import java.io.*;
public class ImportTest {
  public static void main(String[] args) {
    File f = new File(".");
  }
}

Importanweisungen werden durch Semikolon getrennt untereinander geschrieben und beginnen jedes mal mit import.

Ausgenommen sind alle Klassen im Package java.lang. Diese werden immer importiert, ohne dass Sie als Programmierer sich darum kümmern müssen.

Auf das Objekt zugreifen

Nachdem Sie nun ein Objekt erstellt haben, können Sie auch die verfügbaren Methoden des Objektes aufrufen und auf die sichtbaren Attribute zugreifen. Dazu schreiben Sie den Objektnamen gefolgt von einem Punkt (.) und dem Namen der Methode mitsamt Parameter bzw. den Namen des Attributes.

buffer.reverse();

Das übliche, abschließende Semikolon darf natürlich auch hier nicht fehlen. Die Unterkapitel zu 04.03 Klassen werden Ihnen diese Vorgehensweisen noch einmal genauer erläutern.

Statischer Import

Manche Klassen besitzen statische Attribute/Methoden. Diese werden nicht über das Objekt, sondern direkt über die Klasse angesprochen. Zum Beispiel hat die Klasse Math mehrere, statische Methoden und Variablen. Dazu gehört u. a. die Methode random(), welche eine zufällige Zahl zurückliefert, und die Variable PI, welche die Kreiszahl PI bis zu einer bestimmten Genauigkeit repräsentiert. Solche statischen Bestandteile einer Klasse werden entsprechend Klassenattribut bzw. Klassenmethode genannt.

package de.test;
public class StaticTest {
  public static void main(String[] args) {

    System.out.println(Math.random());
    System.out.println(Math.PI);
  }
}

Seit Java 1.5 ist es möglich, solche Klassen/Methoden/Attribute statisch zu importieren.

package de.test;
// Nur die Variable PI importieren
import static java.lang.Math.PI;
public class StaticTest {
  public static void main(String[] args) {

    System.out.println(Math.random());
    System.out.println(PI);
  }
}

Hierzu ergänzen Sie die import-Anweisung um das Schlüsselwort static, und geben (wie oben) das Package, die Klasse und den zu importierenden Attributnamen an. Möchten Sie alles Statische aus einer Klasse importieren, beschränken Sie sich auf das Package, den Klassennamen und einen abschließenden Stern (siehe unten). Mehr zu dem Schlüsselwort static erfahren Sie später im entsprechenden Kapitel 04.03.07 Verwendung von static.

package de.test;
// Alles statische aus Math importieren
import static java.lang.Math.*;
public class StaticTest {
  public static void main(String[] args) {

    System.out.println(random());
    System.out.println(PI);
  }
}

Verwenden Sie statische Importe aber nur in Maßen und auch nur, wenn es auf einem anderen Weg sehr umständlich wäre.

Ein bisschen Theorie

Sie haben jetzt einige praktische Beispiele und Erläuterungen zu Objekten gelesen. Zeit für ein wenig abstrakte Theorie:

Sie wissen bereits, dass ein Objekt aus Methoden und Attributen besteht. Zudem hat ein Objekt einen Zustand, ein Verhalten und eine Identität. Letzteres ist das Unterscheidungsmerkmal zu anderen Objekten – unabhängig von Verhalten und Zustand. Die Operationen bestimmen sein Verhalten und der Zustand eines Objekts wird durch dessen Attributen und Verbindungen zu anderen Objekten definiert.

Ein Objekt kann auf mehrere Wege mit einem anderen Objekt verbunden sein (Assoziation). Dies und noch viel mehr lernen Sie aber detailliert im Kapitel 04.04 UML – Die Sprache der OOP. Stichwörter: Aggregation und Komposition.

Schreibe einen Kommentar

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.