Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger

Kompendium der Informationstechnik  von Sascha Kersken
EDV-Grundlagen, Programmierung, Mediengestaltung
(Die Neuauflage ist erschienen als: "Handbuch für Fachinformatiker")
Buch: Kompendium der Informationstechnik
gp Kapitel 5 Grundlagen der Programmierung
  gp 5.1 Die Programmiersprache C
    gp 5.1.1 Das erste Beispiel
    gp 5.1.2 Elemente der Sprache C
    gp 5.1.3 Die C-Standardbibliothek
  gp 5.2 Java
    gp 5.2.1 Grundlegende Elemente der Sprache Java
    gp 5.2.2 Objektorientierte Programmierung mit Java
  gp 5.3 Perl
    gp 5.3.1 Das erste Beispiel
    gp 5.3.2 Elemente der Sprache Perl
  gp 5.4 Zusammenfassung

gp

Prüfungsfragen zu diesem Kapitel (extern)


Rheinwerk Computing

5.2 Java  downtop

Die Programmiersprache Java wurde 1995 von dem bekannten Server- und Workstation-Hersteller Sun Microsystems vorgestellt. Zu den wichtigsten Entwicklern des Projekts gehören James Gosling und Bill Joy. Java hat vor allen Dingen die Besonderheit, dass der kompilierte Programmcode auf verschiedenen Rechnern und Betriebssystemen ausgeführt werden kann – für diese Systeme ist lediglich Java-Unterstützung in Form einer virtuellen Maschine (JVM – Java Virtual Machine) erforderlich. Virtuelle Java-Maschinen sind für zahlreiche verschiedene Plattformen verfügbar, unter anderem für Windows, Mac  OS und alle UNIX-Varianten. Dieser Ansatz wird von Sun als »Write once, run everywhere« bezeichnet.

Java-Einsatzgebiete

Anfangs wurde Java vor allen Dingen eingesetzt, um so genannte Applets zu schreiben. Dabei handelt es sich um kleine Java-Programme, die in einem Webbrowser ausgeführt werden, der eine JVM enthält. Da für Multimedia-Angebote im Web inzwischen erheblich bessere Lösungen wie beispielsweise Flash verfügbar sind, hat sich der Schwerpunkt der Java-Verwendung auf andere Bereiche verlagert: Java-Anwendungen werden im professionellen Serverbereich eingesetzt, weil sie aufgrund ihrer Plattformunabhängigkeit mit den verschiedensten Systemen kooperieren können; auch zur Entwicklung von Desktop-Anwendungen wie Office- oder Grafikprogrammen wird Java gern genutzt.

Wenn Sie Java-Programme schreiben möchten, brauchen Sie das Java2 Software Development Kit, das Sie sich unter java.sun.com für mehrere Plattformen herunterladen können. Falls Ihr System dort nicht zu finden ist, hilft in der Regel eine Web-Suchmaschine wie etwa Google weiter.

Das Java2 SDK wird in drei verschiedenen Varianten angeboten:

gp  Die Standard Edition (J2SE), auf die sich dieser Abschnitt bezieht, ist für sämtliche Desktop-Anwendungen geeignet.
gp  Die Enterprise Edition (J2EE) enthält Unterstützung für die Entwicklung verteilter, datenbankgestützter Serveranwendungen und wird in Kapitel 14 dieses Buches, Netzwerkanwendungen, kurz vorgestellt.
gp  Die Micro Edition (J2ME) dient der Entwicklung von Anwendungen für mobile Geräte wie Handys oder PDAs und wird in diesem Buch nicht behandelt.

Das Java2 SDK installieren

Die Installation der J2SE selbst ist sehr einfach: Sie laden einfach ein für Ihre Plattform geeignetes Archiv oder ausführbares Programm herunter, das sich in den meisten Fällen per Doppelklick installieren lässt. Das einzige kleine Problem besteht darin, dass Sie zwei Umgebungsvariablen setzen beziehungsweise anpassen müssen, um mit Java arbeiten zu können. Wie Systemvariablen unter verschiedenen Betriebssystemen manipuliert werden, haben Sie bereits in Kapitel 4, Betriebssysteme, erfahren.

Um den Java-Compiler und die JVM von überall her aufrufen zu können, müssen Sie das Unterverzeichnis bin Ihrer Java-Installation zur Umgebungsvariablen path hinzufügen. Außerdem müssen Sie eine weitere Systemvariable namens CLASSPATH einrichten, die auf die Java-Klassenbibliothek verweist – in der Regel das Verzeichnis lib innerhalb der Java-Installation. Zu CLASSPATH werden, durch Semikolon getrennt, auch andere Verzeichnisse (oder Archivdateien wie .zip oder .jar) hinzugefügt, in denen weitere Java-Klassen enthalten sind. Es empfiehlt sich, auch . als Synonym für das aktuelle Arbeitsverzeichnis hinzuzufügen, damit auch Ihre eigenen Java-Programme überall gefunden werden.

Objektorientierung

Der wichtigste Unterschied zwischen Java und C besteht darin, dass Java objektorientiert ist, während C zu den prozeduralen oder imperativen Programmiersprachen zählt. Das objektorientierte Programmieren (OOP) ist ein modernerer Ansatz der Softwareentwicklung. Während in imperativen Sprachen wie C zunächst eine Datenstruktur entwickelt wird, die mit den Programmfunktionen nicht näher verbunden ist, bilden Funktionen und Datenstrukturen bei der OOP eine untrennbare Einheit.

Ein Java-Programm ist immer eine Klassendefinition. Eine Klasse ist das übergeordnete Bauelement der Objektorientierung. Sie besteht aus einer Reihe von Variablen, die als Eigenschaften bezeichnet werden, und aus mehreren Funktionen, die Methoden genannt werden. Durch die Kapselung der Eigenschaften und Methoden zu Klassen lassen sich die verschiedenen Bestandteile der realen Welt oder der zu verwaltenden Daten realitätsnäher nachbilden: Beispielsweise müsste die imperative Nachbildung eines Autos durch externe Funktionen zum »Fahren« (Änderung von Daten wie Tankfüllung oder Kilometerstand) gebracht werden. Ein »objektorientiertes Auto« enthält dagegen einfach eine entsprechende Methode, die aufgerufen wird, sodass das Auto »selber fährt«.

Die Klassendefinition selbst ist lediglich eine Vorlage für die Erzeugung konkreter Objekte. Es können beliebig viele Objekte einer Klasse erzeugt werden; jedes dieser Objekte besitzt alle Eigenschaften, die in der Klasse definiert wurden. Objekte werden auch als Instanzen einer Klasse bezeichnet.

Details verbergen

Einer der wichtigsten Vorteile der Kapselung besteht darin, dass Detaildaten immer nur an einer Stelle verwaltet und verändert werden, was die Häufigkeit von Fehlern erheblich verringert. Außerhalb einer bestimmten Klasse dürfen die Werte von Daten, die Sie »nichts angehen«, nicht manipuliert werden. Um bei dem Auto-Beispiel zu bleiben, sollte beispielsweise der Kilometerstand nur durch die offizielle Methode »Fahren« geändert werden und nicht durch eine direkte Wertzuweisung.

Seit ihrer Entwicklung in den 70er-Jahren wurde die OOP in vielen verschiedenen Programmiersprachen realisiert. Eine der ersten von ihnen war SmallTalk, die das Konzept erstmalig bekannt machte. Die verbreitetsten objektorientierten Sprachen sind heute C++, eine objektorientierte Erweiterung von C, Java und C# (C sharp) von Microsoft. Da C++ nicht konsequent objektorientiert ist, um die Kompatibilität mit C aufrechtzuerhalten, wird an dieser Stelle die Sprache Java besprochen, die sich zwar an C++ anlehnt, aber sämtliches imperative C-Erbe weglässt. C# ist laut Angabe von Microsoft ebenfalls eine Weiterentwicklung von C++, erinnert aber eher an Java. Einige Aspekte von C# werden im Abschnitt Verteilte Anwendungen in Kapitel 14, Netzwerkanwendungen, dargestellt.


Rheinwerk Computing

5.2.1 Grundlegende Elemente der Sprache Java  downtop

Um einen Einstieg in die Java-Programmierung zu finden, sehen Sie in Listing 5.4 gleich das erste Beispielprogramm. Es handelt sich dabei um die Java-Entsprechung des ersten C-Beispielprogramms aus Listing 5.1, was die Unterschiede deutlich macht. Geben Sie das Programm in Ihrem bevorzugten Texteditor ein und speichern Sie es unter Hallo.java – eine Java-Quellcodedatei muss so heißen wie die Klasse, die darin definiert wird, und die Endung .java aufweisen. Dabei müssen Sie die Groß- und Kleinschreibung des Klassennamens genau übernehmen; üblicherweise beginnen Klassennamen mit einem Großbuchstaben.

Listing 5.4   Das erste Java-Beispiel

import java.io.*;
 
public class Hallo
{
   public static void main (String args[])
   {
      BufferedReader eingabe = new BufferedReader (
           new InputStreamReader (System.in));
      String name = "";
      System.out.println ("Hallo Welt!");
      System.out.print ("Ihr Name, bitte: ");
      try {
         name = eingabe.readLine();
      }
      catch (IOException e) {}
      System.out.println ("Hallo " + name + "!");
   }
}

Java kompilieren

Wenn Sie zuvor Ihre path- und CLASSPATH-Einstellungen korrekt vorgenommen haben, können Sie das Programm nun folgendermaßen kompilieren, wenn Sie sich im entsprechenden Verzeichnis befinden:

$ javac Hallo.java

Falls Sie keine Fehlermeldung erhalten, finden Sie im aktuellen Verzeichnis die fertig kompilierte Datei Hallo.class vor. Sie können das Programm anschließend folgendermaßen starten:

$ java Hallo

Das ausführbare Programm java aktiviert die JVM; als Kommandozeilenargument wird der Name einer kompilierten Java-Klasse ohne Dateiendung angegeben.

Wie Sie sehen, ist dieses Programm erheblich komplexer als die C-Version, obwohl es dieselbe Aufgabe erfüllt. Im Folgenden wird das Programm zeilenweise erläutert:

gp  import java.io.*;
Mit Hilfe der Anweisung import werden bestimmte Teile der Java-Klassenbibliothek importiert. Der Vorgang ist vergleichbar mit dem Einbinden von Header-Dateien mittels #include. Allerdings ist import eine normale Java-Anweisung; einen Präprozessor gibt es nicht. Außerdem unterscheiden sich die importierten Klassen formal nicht von Ihren eigenen Programmen – eine Aufteilung in Header- und Programmdatei ist in Java ebenfalls nicht vorgesehen.
    java.io.* bezeichnet alle Klassen, die im Verzeichnis io der grundlegenden Klassenbibliothek liegen. Es handelt sich um eine Sammlung von Klassen für die Ein- und Ausgabe. Solche Bestandteile der Klassenbibliothek werden als Packages bezeichnet.
       
gp  public class Hallo
Mit dem Schlüsselwort class wird eine Klassendefinition eingeleitet. Mit Hilfe von public wird die definierte Klasse für sämtliche anderen Klassen, das heißt für alle Programme, zugänglich.
gp  public static void main (String args[])
Wie in C steht main() für das Hauptprogramm. Allerdings gibt es in einem Java-Programm einige wichtige formale Unterschiede: Da das Betriebssystem diese Methode von außen aufrufen muss, wird das Schlüsselwort public benötigt. Alle Bestandteile einer Klasse, die nicht public sind, stehen außerhalb der Klasse selbst nicht zur Verfügung. static wird benötigt, weil von dieser Klasse kein konkretes Objekt abgeleitet wird. Eine Klasse ist eigentlich nur eine Art Bauanleitung für Objekte; ihre static-Bestandteile können aber ohne weiteres verwendet werden. In der Regel hat main() in Java den Datentyp void. Das Array args[] nimmt Kommandozeilenargumente entgegen.
gp  BufferedReader eingabe = new BufferedReader (new InputStreamReader (System.in));
Diese verschachtelte Operation sorgt für ein Objekt namens eingabe, das zeilenweise von der Standardeingabe lesen kann. Im Kern von Java ist leider keine Möglichkeit gegeben, ganze Zeilen einzulesen. Deshalb wird die Standardeingabe – repräsentiert durch System.in – in ein Objekt vom Typ InputStreamReader (Lesevorrichtung für kontinuierliche Datenströme) verpackt, das wiederum von einem BufferedReader (zuständig für die Zwischenspeicherung von Eingabedaten) umhüllt wird. Solche verschachtelten Objektkonstruktionen machen Java relativ kompliziert, aber durch die große Auswahl spezialisierter Klassen auch sehr flexibel.
gp  String name = "";
Im Gegensatz zu C stellt Java einen echten String-Datentyp zur Verfügung, der als Klasse realisiert ist. Diese Anweisung erzeugt eine String-Variable mit der Bezeichnung name; ihr wird als Anfangswert der leere String zugewiesen, weil es beim späteren Eingabeversuch passieren könnte, dass sie gar keinen Wert erhält.
gp  System.out.println ("Hallo Welt!");
Die Methode println() der Standardausgabe (System.out) gibt einen übergebenen String mit anschließendem Zeilenumbruch aus.
gp  System.out.print ("Ihr Name, bitte: ");
Die Methode print() gibt dagegen einen String ohne Zeilenumbruch aus.
gp  try {...}
In einen try-Block werden Anweisungen immer dann geschrieben, wenn sie einen möglichen Fehler produzieren könnten. Laufzeitfehler werden in Java als so genannte Ausnahmen (Exceptions) betrachtet, die mittels try/catch (siehe unten) abgefangen und sinnvoll behandelt werden können.
gp  name = eingabe.readLine();
Die Methode readLine() der Klasse BufferedReader liest eine Zeile aus einem Eingabestrom, in diesem Fall von der Standardeingabe.
gp  catch (IOException e) {}
Mit Hilfe von catch() kann eine Ausnahme abgefangen werden, die innerhalb des vorangegangenen try-Blocks ausgelöst wurde. In diesem Fall handelt es sich um eine IOException, also einen Ein-/Ausgabefehler. In den geschweiften Klammern kann Code für spezielle Maßnahmen zur Fehlerbehandlung stehen. Die wichtigste Aufgabe von try/catch besteht darin, den sofortigen Programmabbruch bei einem Fehler zu verhindern.
gp  System.out.println ("Hallo " + name + "!");
Das Besondere an dieser Ausgabeanweisung ist die Verkettung mehrerer Strings durch den Operator +.

Unterschiede zu C

Erfreulicherweise müssen viele grundlegende Konzepte von Java nicht mehr erläutert werden, weil sie mit C übereinstimmen. Beispielsweise sind die einfachen Datentypen, Ausdrücke, Operatoren und Kontrollstrukturen nahezu identisch, deshalb werden an dieser Stelle nur die wesentlichen Unterschiede aufgezählt. Hier ist nicht die Tatsache gemeint, dass Java objektorientiert ist, sondern es geht nur um die Unterschiede bei vergleichbaren Elementen.

gp  Im Gegensatz zu C haben die Integer-Datentypen in Java eine festgelegte Bit-Breite: int ist 32 Bit groß, short 16 Bit, long 64 Bit.
gp  Java definiert einen separaten Datentyp für 8-Bit-Integer namens byte; char wird dagegen nur zur Darstellung eines einzelnen Zeichens verwendet und besitzt eine Breite von 16 Bit, um Unicode-Zeichen darzustellen.
gp  Java kennt einen Datentyp für boolesche Wahrheitswerte: boolean. Er kann nur die vorgegebenen Wahrheitswerte true oder false annehmen. Sämtliche Bedingungsprüfungen für Kontrollstrukturen müssen in Java einen boolean-Wert haben; wenn Sie also beispielsweise prüfen möchten, ob die Variable a den Wert 0 hat, müssen Sie den Vergleich a == 0 explizit hinschreiben! Die typische C-Kurzschreibweise !a ist nicht zulässig. Aus diesem Grund wird Java als stark typisierte Sprache bezeichnet, weil sehr streng über die Einhaltung der korrekten Datentypen gewacht wird.
gp  Die Syntax für die Deklaration eines Arrays mit einer festgelegten Anzahl von Elementen unterscheidet sich von C: Es erfolgt ein Aufruf der Objekterzeugungsmethode new, gefolgt vom Datentyp und der Elementanzahl:
int werte[] = new int[20];
gp  Variablen können in Java an einer beliebigen Stelle deklariert werden. Beachten Sie allerdings, dass eine Variable, die innerhalb des Anweisungsblocks einer Kontrollstruktur deklariert wird, nur in diesem Block gilt. Beispielsweise produziert der folgende Code einen Fehler:
for (int i = 0; i < 10; i++) {
   ...
}
System.out.println (i);    // i existiert hier nicht mehr!
gp  Der einzige wichtige Operator, den Java zusätzlich zu C definiert, ist der String-Verkettungs-Operator + (siehe Beispiel oben). Er ist zwar praktischer als die umständliche C-Funktion strcat(), aber dafür sorgt er mitunter für Verwirrung, weil er mit dem arithmetischen + verwechselt werden kann. Beispielsweise gibt die folgende Anweisung Summe: 35 aus:
System.out.println ("Summe: " + 3 + 5);
gp  Andere Operationen mit Strings werden über Methoden der Klasse String realisiert. Jeder String-Ausdruck ist automatisch eine Instanz dieser Klasse, auch ohne formale objektorientierte Instanzerzeugung.
    Sie können zum Beispiel zwei Strings vergleichen, indem Sie string1.equals (string2) aufrufen; string1 und string2 können dabei Variablen, Literale oder Ausdrücke mit dem Datentyp String sein. Eine Variante ist string1.equalsIgnoreCase (string2) für einen Vergleich ohne Berücksichtigung von Groß- und Kleinschreibung. Das Ergebnis ist jeweils true, wenn die Strings gleich sind, oder false, wenn sie verschieden sind.
       
    Einen allgemeineren Vergleich von Strings – analog zur C-Funktion strcmp() – bietet die Methode string1.compareTo (string2). Wie dort ist das Ergebnis unter 0, wenn string1 im Zeichensatz vor string2 steht, 0, wenn die beiden Strings gleich sind, und größer als 0, wenn string1 nach string2 kommt.
       
    Weitere interessante String-Methoden sind folgende:
       
string1.charAt (pos) gibt das Zeichen an der Position pos zurück (Positionen beginnen bei 0). Zum Beispiel gibt "Köln".charAt (1) das 'ö' zurück. Beachten Sie, dass der Datentyp des Rückgabewerts char und nicht String ist. string1.substring (anfang, ende) gibt die Zeichen von der Position anfang bis ausschließlich ende zurück. Beispielsweise ergibt "Köln".substring (1, 3) den String "öl". string1.indexOf (ch) gibt die erste Position in string1 zurück, an der das Zeichen ch (Typ char) vorkommt, oder –1, wenn ch gar nicht vorkommt. Eine alternative Form sucht nach dem Vorkommen eines Teilstrings: string1.indexOf (string2). lastIndexOf() gibt dagegen die Position des letzten Vorkommens des gesuchten Zeichens oder Teilstrings zurück. string1.length() liefert die Länge des Strings in Zeichen.
gp  Im Unterschied zu C verwendet Java keine Zeiger. Dies entfernt eine der wichtigsten Quellen für Fehler und Sicherheitsprobleme aus der Sprache. Für einen Call by Reference werden stattdessen Objektreferenzen verwendet (siehe unten).
gp  In Java gibt es zusätzliche Arten von Kommentaren. Der mit C++ eingeführte einzeilige Kommentar beginnt mit // und reicht bis zum Ende der Zeile. Daneben existiert der spezielle JavaDoc-Kommentar, der mit /** beginnt und mit */ endet. Das mit dem Java2 SDK gelieferte Programm javadoc kann aus diesen Kommentaren automatisch eine Programmdokumentation generieren.

Rheinwerk Computing

5.2.2 Objektorientierte Programmierung mit Java  toptop

Sämtliche Klassen der Java-Klassenbibliothek und alle, die Sie selbst definieren, stammen direkt oder indirekt von der Klasse Object ab. Object gehört zum Kern-Package java.lang, das nicht mittels import eingebunden werden muss – wie der Name schon sagt, stellt lang den Sprachkern von Java zur Verfügung, darunter wichtige Klassen wie String, Math (mathematische Konstanten und Funktionen) oder System (wichtige Betriebssystemschnittstellen).

Objektorientierte Programmierung lässt sich am besten anhand eines Beispiels veranschaulichen. Da das weiter oben erwähnte Auto-Beispiel in fast jedem Buch über OOP verwendet wird, soll hier zur Abwechslung ein anderes zum Einsatz kommen: Es werden die verschiedenen Arten von Personen in einer Ausbildungsumgebung modelliert. Die grundlegende Klasse, von der alle anderen abgeleitet werden, heißt Person (Listing 5.5) und definiert diejenigen Eigenschaften, die alle beteiligten Personen gemeinsam haben.

Listing 5.5   Personendaten als Java-Klasse

public class Person
{
   // Eigenschaften:    private String name;
   private String vorname;
   private int alter;
 
   // Konstruktor:
   public Person (String n, String v, int a)
   {
      this.name = n;
      this.vorname = v;
      this.alter = a;
   }
 
   // Methoden:
   public void geburtstag()
   {
      this.alter++;
   }
 
   public String getName()
   {
      return this.vorname + " " + this.name;
   }
 
   public int getAlter()
   {
      return this.alter;
   }
}

Speichern Sie diese Klassendefinition zunächst unter Person.java. Sie lässt sich ohne weiteres kompilieren, aber natürlich nicht ausführen, da sie wegen der fehlenden main()-Methode kein ausführbares Programm ist.

Wie Sie möglicherweise bemerkt haben, handelt es sich bei diesem Beispiel um die Java-Entsprechung der C-Struktur, in der ebenfalls Personendaten abgelegt wurden. In Java gibt es struct übrigens nicht, weil es sich dabei aus der Sicht der OOP lediglich um den Sonderfall einer Klasse ohne Methoden handelt.

Die einzelnen Bestandteile der Klassendefinition werden nun kurz erläutert:

gp  Als Erstes werden die verschiedenen Eigenschaften der Klasse deklariert. Sie haben die Geheimhaltungsstufe private, sind also außerhalb eines Objekts dieser Klasse nicht sichtbar. Innerhalb der Methoden der Klasse können die Eigenschaften mit einem vorangestellten this. angesprochen werden. this repräsentiert während der Ausführung der Konstruktoren und Methoden einer Klasse die aktuelle Instanz selbst.
gp  Der Konstruktor ist eine spezielle Methode, die immer dann aufgerufen wird, wenn eine Instanz der Klasse erzeugt wird. Konstruktoren tragen stets den Namen der Klasse selbst und haben keinen Datentyp. Sie werden typischerweise verwendet, um das neu erzeugte Objekt zu initialisieren, etwa, um den Eigenschaften Anfangswerte zuzuweisen.
gp  Die drei Methoden dieser Klasse besitzen alle die Geheimhaltungsstufe public, damit sie von außen für Instanzen der Klasse aufgerufen werden können. Diese Methoden sind die offiziellen Schnittstellen, über die die Werte der Eigenschaften gelesen oder geändert werden können. Über dieses erlaubte Maß hinaus besteht keine weitere Möglichkeit dazu.

Um die Klasse Person ausprobieren zu können, wird das folgende kleine Programm verwendet:

public class PersonenTest
{
   public static void main (String args[])
   {
      Person klaus = new Person ("Schmitz", "Klaus", 42);
      System.out.println ("Person: " + klaus.getName());
      klaus.geburtstag();
      System.out.println ("Neues Alter: " + klaus.getAlter());
   }
}

Instanziierung

Eine Instanz ist formal eine Variable, deren Datentyp die entsprechende Klasse ist. Der Konstruktor der Klasse wird mittels new aufgerufen. Die Methoden werden durch einen . (Punkt) vom Instanznamen (in diesem Beispiel: klaus) getrennt.

Überladen von Konstruktoren und Methoden

Mitunter ist es nützlich, ein Objekt mit Hilfe verschiedener Eingabewerte zu erzeugen. Daher besteht die Möglichkeit, mehrere Konstruktoren zu definieren. Auch bestimmte Methoden könnten ihre Funktionalität auf verschiedene Art und Weise zur Verfügung stellen, die ebenfalls von unterschiedlichen Parametern abhängt. Die mehrfache Definition eines Konstruktors oder einer Methode mit verschiedenen Parametern wird als Überladen bezeichnet.

Innerhalb der Klasse Person könnten Sie beispielsweise einen alternativen Konstruktor definieren, der aufgerufen wird, wenn der Vorname unbekannt ist:

public Person (String n, int a)
{
   this.name = n;
   this.alter = a;
   this.vorname = "";
}

Da bereits ein anderer Konstruktor definiert ist, können Sie ihn innerhalb des neuen Konstruktors aufrufen. Dadurch lässt sich der zweite Konstruktor erheblich kürzer fassen:

public Person (String n, int a)
{
   this (n, "", a);
}

Je nachdem, wie Sie eine Instanz der Klasse Person erzeugen, wird einer der beiden Konstruktoren aufgerufen:

Person klaus = new Person ("Schmitz", "Klaus", 42);
     // ruft den ersten Konstruktor auf
Person meyer = new Person ("Meyer", 32);
     // ruft den zweiten Konstruktor auf

Das Überladen von Methoden funktioniert genauso. Beispielsweise könnte eine weitere Version der Methode geburtstag() existieren, die das Alter explizit einstellt:

public void geburtstag (int a)
{
   this.alter = a;
}

Wenn Sie einfach geburtstag() aufrufen, wird die Person wie gehabt ein Jahr älter; ein Aufruf wie geburtstag (33) ruft dagegen die neue Methode auf und setzt das Alter auf den angegebenen Wert.

Vererbung

Eines der wichtigsten Merkmale der OOP besteht darin, dass Sie speziellere Klassen von allgemeineren ableiten können. Dies wird als Vererbung bezeichnet. Die allgemeine, übergeordnete Klasse heißt Elternklasse, während die speziellere, untergeordnete Kindklasse oder abgeleitete Klasse genannt wird. In der abgeleiteten Klasse müssen nur diejenigen Eigenschaften und Methoden definiert werden, die in der Elternklasse noch nicht vorhanden waren oder geändert wurden.

In Java wird die Vererbung durch das Schlüsselwort extends gekennzeichnet. Beachten Sie, dass die abgeleitete Klasse nur diejenigen Bestandteile der Elternklasse verwenden kann, deren Geheimhaltungsstufe nicht private ist. Da es nicht empfehlenswert ist, allzu viele Komponenten einer Klasse als public zu definieren, bietet Java die spezielle Geheimhaltungsstufe protected an. Eigenschaften und Methoden, die protected sind, werden nicht nach außen veröffentlicht, können aber in Kindklassen eingesetzt werden.

Bevor Sie die folgenden Klassen von Person ableiten können, müssen Sie dort jedes Vorkommen von private durch protected ersetzen und die Datei neu kompilieren.

Die folgenden beiden Klassen, Lehrer und Schueler, müssen in gleichnamigen Dateien gespeichert und können dann kompiliert werden:

public class Lehrer extends Person
{
   // zusätzliche Eigenschaft:
   private String fach;
 
   // Konstruktor:
   public Lehrer (String n, String v, int a, String f)
   {
      super (n, v, a);
      this.fach = f;
   }
 
   // Neue Methode:
   public String getFach()
   {
      return this.fach;
   }
}
 
public class Schueler extends Person
{
   // zusätzliche Eigenschaft:
   private int klasse;
 
   // Konstruktor:
   public Schueler (String n, String v, int a, int k)
   {
      super (n, v, a);
      this.klasse = k;
   }
 
   // Neue Methoden:
   public int getKlasse()
   {
      return this.klasse;
   }
 
   public void versetzung()
   {
      this.klasse++;
   }
}

Die einzige erklärungsbedürftige Besonderheit in den abgeleiteten Klassen dürfte das Schlüsselwort super sein. Es ruft explizit den durch die Auswahl der Argumente spezifizierten Konstruktor der Elternklasse auf.

In einem Programm können diese beiden Klassen beispielsweise folgendermaßen verwendet werden:

Lehrer welsch = new Lehrer ("Welsch", "Jo", 64, "Mathe");
System.out.println (welsch.getName() + " unterrichtet " +
     welsch.getFach());
 
Schueler tim = new Schueler ("Witt", "Tim", 16, 11);
tim.versetzung();
System.out.println (tim.getName() + " versetzt in Klasse "
     + tim.getKlasse());

Die Ausgabe dieser beiden Beispiele sollte so aussehen:

Jo Welsch unterrichtet Mathe
Tim Witt versetzt in Klasse 12

Interfaces

Anders als in C++ und anderen Sprachen ist in Java keine Mehrfachvererbung erlaubt; eine Klasse kann also immer nur von genau einer anderen abgeleitet werden. Mitunter kann dies sehr lästig sein: Zwei verschiedene Klassen, die ansonsten nichts miteinander zu tun haben, könnten einen gewissen gemeinsamen Aspekt aufweisen und von einer anderen Stelle aus unter diesem Aspekt betrachtet werden. Beispielsweise ist ein Buch ein völlig anderes Objekt als eine Suppenschüssel. Beide könnten aber als Artikel im gleichen Supermarkt verkauft werden und als solche gemeinsame Eigenschaften wie eine Artikelnummer oder einen Preis aufweisen.

Um Objekte beliebiger Klassen unter einem bestimmten Gesichtspunkt als dieselbe Art von Objekt betrachten zu können, verwendet Java das Verfahren der Interfaces. Ein Interface ähnelt einer Klassendefinition, enthält aber lediglich Methodendeklarationen, die nicht implementiert werden, also keine Anweisungen enthalten. Eine Klasse, die ein Objekt dieser Art sein soll, muss alle im Interface deklarierten Methoden konkret implementieren.

Das folgende Beispiel definiert ein Interface namens Artikel, das verschiedene Methoden deklariert:

public interface Artikel
{
   public int getArtNr();
   public int getPreis();
}

Die Klasse Buch implementiert das Interface Artikel und definiert daher die Methoden getArtNr() und getPreis():

public class Buch implements Artikel
{
   private int artNr;
   private int preis;
   ...
   public int getArtNr()
   {
      return artNr;
   }
 
   public int getPreis()
   {
      return preis;
   }
}

Der Hauptnutzen dieser Interface-Implementierung besteht darin, dass eine Methode, die mit verschiedenen Artikeln arbeitet, diese alle als Daten vom gleichen Typ ansprechen kann, nämlich Artikel.

In der Java-Klassenbibliothek sind Unmengen von Interfaces enthalten, die Sie in Ihren eigenen Programmen implementieren können. Bekannte Beispiele dafür sind die Interfaces Serializable oder Runnable. Serializable wird für Klassen verwendet, deren Datenbestand sich als sequenzieller Datenstrom darstellen (serialisieren) lässt, während Runnable von Programmen implementiert wird, die als Thread laufen sollen (siehe Kapitel 6, Konzepte der Programmierung).


Was ist mit der Java-Klassenbibliothek? Eine ausführlichere Beschreibung von Java würde nach der Darstellung der bisher gebotenen Grundlagen dazu übergehen, verschiedene Komponenten der mit dem Java2 SDK gelieferten Klassenbibliothek zu beschreiben. Diese Bibliothek enthält Dutzende von Packages mit Unmengen von Klassen, die wiederum unzählige Methoden besitzen. Da nicht die geringste Chance besteht, einer solchen Informationsmenge in einem Buch wie diesem gerecht zu werden, habe ich mich entschlossen, an dieser Stelle gar nicht weiter auf die Klassenbibliothek einzugehen. Stattdessen lernen Sie im nächsten Kapitel und in einigen späteren Kapiteln jeweils thematisch passende Beispielklassen kennen. Für eine ausführliche Darstellung der faszinierenden Programmiersprache Java empfehle ich beispielsweise das hervorragende Buch »Java ist auch eine Insel« von Christian Ullenboom (Galileo Computing).

  
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung


IT-Handbuch
für Fach-
informatiker

Java ist auch
eine Insel

Linux
Handbuch

Computer
Netzwerke

Schrödinger
lernt HTML5,
CSS3 und
JavaScript
Versandkostenfrei bestellen in Deutschland und Österreich
Info





Copyright © Rheinwerk Verlag GmbH 2004
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Rheinwerk Computing]

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de