2.01 Klassen und Objekte

Inhalt dieser Seite

Einführung

Die grundlegende Philosophie des objektorientierten Programmierens ist, Objekte der realen Welt anhand ihrer Eigenschaften und Fähigkeiten zu modellieren. Gleichartige Objekte, d.h. Objekte, die sich durch dieselben Eigenschaften und Fähigkeiten beschreiben lassen, fasst man dabei zu sogenannten Klassen zusammen. Bevor wir aber viel theoretisieren, schauen wir uns ein Beispiel an:

Ein Klassendiagramm der Klasse Auto. Die Attribute baujhar,marke, kilometerstand, automatik und preis werden verwendet.
Ein erstes Klassendiagramm. Ein paar Details werden später noch ergänzt.

Dies ist ein sogenanntes Klassendiagramm. Einige Details fehlen in diesem Diagramm noch, da diese erst später für uns Sinn ergeben. Der Aufbau eines solchen Diagramms ist wie folgt:

  • Im ersten Feld steht (in Fettdruck) der Name der Klasse.
  • In dem zweiten Feld stehen die Eigenschaften, die uns an Objekten dieser Klasse interessieren. Diese
    Eigenschaften nennt man die Attribute dieser Klasse. Man gibt dort an, von welchem Typ diese Attribute sind.
  • Im dritten Feld gibt man Fähigkeiten von Objekten dieser Klasse an. Diese nennt man die Methoden der Klasse. Anders ausgedrückt kann man sich auch vorstellen, dass dies die möglichen Anweisungen sind, auf die ein Objekt dieser Klasse sinnvoll reagieren kann. Man gibt dort auch an, ob diese Methoden einen oder mehrere Parameter benötigen und von welchem Typ diese sein müssen. Sollten sie einen Rückgabewert liefern, so wird auch sein Typ angegeben. Die Methoden der Klasse Auto, die oben angegeben sind, liefern keinen Rückgabewert. Zu Methoden mit Rückgabewert kommen wir noch später.

Sehen wir uns einmal an, wie wir diese Klasse in Java umsetzen könnten:

public class Auto {

  // Attribute
  int baujahr;
  String marke;
  int kilometerstand;
  boolean automatik;	
  int preis;

  // Methoden
  public void macheProbefahrt(int pKilometer){
    kilometerstand = kilometerstand + pKilometer;
  }

  public void aenderePreisUm(int pAenderung){
    if (preis+pAenderung>0){
      preis = preis+pAenderung;
    }else{
      System.out.println("Die Änderung ist nicht zulässig!");
    }
  }

}

Beachte, dass man üblicherweise die Namen von Attributen und Methoden in Java klein schreibt. Außerdem sollten wir keine Umlaute verwenden, da diese Schwierigkeiten verursachen können.

Vielleicht fällt Dir auf, dass man die von uns programmierte Klassen nicht starten kann. Dies ist aber typisch für das objektorientierte Programmieren: Man stellt zunächst einige Klassen bereit und dann schreibt man ein Programm, das die vorher vorbereiteten Klassen verwendet.

Hier ein kleines Beispielprogramm, das die Klasse Auto verwendet:

public class Autotest {

  public static void main(String[] args) {
    
    // Ein Auto wird erstellt:
    Auto meinErstesAuto;
    meinErstesAuto = new Auto();
    
    // Die Werte der Attribute werden gesetzt:
    meinErstesAuto.baujahr = 1985;
    meinErstesAuto.marke = "DeLorean";
    meinErstesAuto.kilometerstand = 54000;
    meinErstesAuto.automatik = false;
    meinErstesAuto.preis = 60000;
    
    // Eine Probefahrt von 5 km findet statt:
    meinErstesAuto.macheProbefahrt(5);
    
    // Der Kilometerstand wird ausgegeben:
    System.out.println(meinErstesAuto.kilometerstand);
    
  }

}

Um es noch einmal zu betonen: Wir verwenden nun zwei Dateien, nämlich Auto.java und Autotest.java. Nur Autotest.java kann gestartet werden, weil nur hier eine main-Methode vorhanden ist.

Sehen wir uns die Anweisungen von Autotest noch einmal im Detail an.

Zunächst wird mit Auto meinErstesAuto;eine Variable vom Typ Auto mit Namen meinErstesAuto deklariert. Neben den uns bekannten Datentypen, die Java ohnehin schon bietet (int, double, String etc.) steht uns also nun der von uns selbst erschaffene Typ Auto ebenfalls zur Verfügung. Mit der folgenden Anweisung meinErstesAuto = new Auto(); wird dann ein neues Objekt der Klasse Auto erschaffen und der Variablen meinErstesAuto zugewiesen. Wir hätten dies übrigens auch in einem Schritt mit der Anweisung meinErstesAuto = new Auto(); machen können.

Es existiert nun also ein Auto, auf das wir Dank der Variablen meinErstesAuto zugreifen können. Man sagt auch, dass nun eine Instanz der Klasse Auto erstellt wurde.

In den nun folgenden Anweisungen greifen wir auf die verschiedenen Attribute dieses Autos zu. Beispielsweise setzen wir den Wert des Attributs baujahr auf 1985. Das Schema ist dabei immer gleich; zuerst kommt der Name der Variablen, unter der das Objekt abgelegt wurde, dann ein Punkt gefolgt vom Namen des Attributs.

Fast genauso können wir auch auf die Methoden des Objekts zugreifen. Bei den Methoden ist jedoch zu beachten, dass bei diesen am Ende immer Runde Klammern stehen müssen. Wenn die Methode einen oder mehrere Parameter verlangt, kommen Werte für die Parameter in die Klammern. Das sehen wir beim Aufruf der Methode für die Probefahrt: meinErstesAuto.macheProbefahrt(5); Selbst wenn eine Methode keinen Parameter verlangt, müssen wir die runden Klammern schreiben. Diese sind dann aber leer. Ein Beispiel dazu werden wir weiter unten sehen.

Konstruktoren

In Autotest haben wir eben zuerst ein Auto ohne Eigenschaften erschaffen und erst anschließend die Attribute mit Daten gefüllt. Das werden wir ab nun aber eleganter mittels eines sogenannten Konstruktors erledigen.

Einen Konstruktor kann man sich als eine Bauanleitung vorstellen: Er gibt an, welche Daten man zur Erschaffung eines Objektes dieser Klasse benötigt. Sehen wir uns hier einen möglichen Konstruktor für unsere Klasse Auto an:

public class Auto {

  // Attribute
  int baujahr;
  String marke;
  int kilometerstand;
  boolean automatik;	
  int preis;

  // Konstruktor
  public Auto(int pBaujahr, String pMarke, int pKilometerstand, boolean pAutomatik, int pPreis){
    baujahr = pBaujahr;
    marke = pMarke;
    kilometerstand = pKilometerstand;
    automatik = pAutomatik;
    preis = pPreis;
  }

  // Methoden
  public void macheProbefahrt(int pKilometer){
    kilometerstand = kilometerstand + pKilometer;
  }

  public void aenderePreisUm(int pAenderung){
    if (preis+pAenderung>0){
      preis = preis+pAenderung;
    }else{
      System.out.println("Die Änderung ist nicht zulässig!");
    }
  }

}

Der Konstruktor sieht im Grunde aus wie eine Methode mit mehreren Parametern. In diesem Fall sind es fünf Parameter, wobei jeder einem der Attribute entspricht. Die einzige Aufgabe des Konstruktors besteht in diesem Fall darin, die Werte für die Parameter an die Attribute zu übergeben. Etwas deutlicher wird dies vielleicht, wenn wir uns eine angepasste Version von Autotest ansehen:

public class Autotest {

  public static void main(String[] args) {
    
    // Ein Auto wird erstellt:
    Auto meinErstesAuto;
    meinErstesAuto = new Auto(1985, "DeLorean", 54000, false, 60000);
    
    // Eine Probefahrt von 5 km findet statt:
    meinErstesAuto.macheProbefahrt(5);
    
    // Der Kilometerstand wird ausgegeben:
    System.out.println(meinErstesAuto.kilometerstand);
    
  }

}

Bereits beim Erschaffen des Objektes geben wir nun alle Werte für die Attribute an. Dabei müssen wir uns genau an die im Konstruktor angegebene Reihenfolge halten.

An dieser Stelle könnte man einwenden, dass Java doch wohl von selbst darauf kommen könnte, dass genau diese Werte angegeben werden müssen. Dies sind ja schließlich genau die Attribute der Klasse Auto. Warum müssen wir dies selbst noch einmal in einem Konstruktor deutlich machen? Der Punkt ist, dass es durchaus vorkommen kann, dass nicht alle Attribute beim Erschaffen angegeben werden müssen. Stellen wir uns vor, wir würden einen Neuwagen erschaffen. Dann hätte dieser natürlichen einen Kilometerstand von 0 km und wäre im aktuellen Jahr (momentan das Jahr 2016) gebaut. Wir können einen dazu passenden Konstruktor ebenfalls hinzufügen:

public class Auto {

  // Attribute
  int baujahr;
  String marke;
  int kilometerstand;
  boolean automatik;	
  int preis;

  // Konstruktor
  public Auto(int pBaujahr, String pMarke, int pKilometerstand, boolean pAutomatik, int pPreis){
    baujahr = pBaujahr;
    marke = pMarke;
    kilometerstand = pKilometerstand;
    automatik = pAutomatik;
    preis = pPreis;
  }

  // weiterer Kontruktor für Neuwagen
  public Auto(String pMarke, boolean pAutomatik, int pPreis){
    baujahr = 2016;
    kilometerstand = 0;

    marke = pMarke;
    automatik = pAutomatik;
    preis = pPreis;
  }

  // Methoden
  public void macheProbefahrt(int pKilometer){
    kilometerstand = kilometerstand + pKilometer;
  }

  public void aenderePreisUm(int pAenderung){
    if (preis+pAenderung>0){
      preis = preis+pAenderung;
    }else{
      System.out.println("Die Änderung ist nicht zulässig!");
    }
  }

}

Der neue Konstruktor verlangt nur drei Parameter. Die Werte für die Attribute baujahr und kilometerstand legt er automatisch fest.

Sehen wir uns auch dazu ein Beispiel an:

public class Autotest {

  public static void main(String[] args) {
    
    // Ein Auto wird erstellt:
    Auto meinErstesAuto = new Auto(1985, "DeLorean", 54000, false, 60000);
    
    // Ein Neuwagen wird erstellt:
    Auto meinNeuesAuto = new Auto("TranAm", true, 75000);
    
    System.out.println(meinNeuesAuto.baujahr);

  }

}

Hier sehen wir die beiden Konstruktoren im Einsatz. Zur Kontrolle wird das Baujahr des zweiten Autos einmal ausgegeben.

Java erkennt übrigens aufgrund der Anzahl und der Typen der Parameter, welcher der Konstruktoren gemeint ist. Solange wir nicht dieselbe Anzahl und Reihenfolge von Datentypen nochmal verwenden, können wir so viele Konstruktoren hinzufügen wie wir möchten.

Auch im Klassendiagramm halten wir die Konstruktoren fest:

Das Klassendiagramm mit ergänzten Kontstruktoren. Sie werden als erste Methoden angegeben.
Die Konstruktoren wurden ergänzt. Weitere Details folgen aber immer noch.

4 Gedanken zu „2.01 Klassen und Objekte“

  1. Hallo
    Ich bin Sven Brodowski aus Heilbronn , ich bin 53 Jahre alt
    und lerne jetzt noch Java

    Ihre Videos sind excelent.

    Ein richtig gute detailierte Erklärung,
    so dass auch ich noch gut den Stoff
    nachvollzidhen kann.

    Was ich aber nicht ganz vetstehe
    ist das nach dem Konstruktor,
    das Wort this fehlt, ich weiss
    man kann es weglassen.

    Aber Warum?

    Mfg
    Sven Brodowski

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.