zurück zur Liste

Java - Programmierparadigmen, Architekturprinzipien, Datenstrukturen & Algorithmen

Anm.:
  1. Dass der geneigte Leser die Sprache Java auf ALP2-Niveau beherrscht, wird vorausgesetzt. Insofern lag die Schwierigkeit beim Schreiben haupsächlich in der Reduktion auf das Wesentliche, da man die Balance zwischen Verständlichkeit und Wiederholung von bekanntem finden musste. Also im Zweifel noch mal nachrecherchieren (s.a. Links) bzw. überspringen.
  2. Da es in Java keine Funktionen, sondern nur Methoden (die auf Objekten arbeiten) gibt, werden die beiden Begriffe hier synonym verwendet.

Objektorientierung

Attribute & Sichtbarkeit

Ein Bezeichner (eine Variable) x heißt sichtbar an einer Programmstelle, wenn er in einem der die Programmstelle umgebenden Blöcke vereinbart wurde. Man unterscheidet innerhalb von Klassen zwischen globalen und lokalen Variablen. Während globale Variablen innerhalb der ganzen Klasse gültig sind, haben lokale Variablen nur einen begrenzten Geltungsbereich (innerhalb ein Methode, Schleife oder eines Blocks).

Lokale Variablen verdecken globale, wenn sie denselben Bezeichner haben. D.h.: Existiert eine globale Variable a und definiert eine Methode erneut eine Variable a, so wird innerhalb der Methode durch den Bezeichner 'a' immer die lokale Variable angesprochen. Auf die globale Variable kann mithilfe des Schlüsselworts this explizit zugegriffen werden.

Die Sichtbarkeit von Variablen kann durch die Attribute public, private und protected beeinflusst werden:

SichtbarkeitInnerhalb der PackageAbgeleitete KlassenAußerhalb der Package
privateunsichtbarunsichtbarunsichtbar
defaultsichtbarunsichtbarunsichtbar
protectedsichtbarsichtbarunsichtbar
publicsichtbarsichtbarsichtbar

Java-Klassen können entweder mit dem Attribut public versehen werden (dann sind sie von überall erreichbar) oder Attributfrei sein. In diesem Fall haben sie default-Sichtbarkeit und können nur von Klassen aus derselben Package erreicht werden.

Beispiel:

package fahrzeuge;

public class Auto {

  private int a = 1;   /* a ist globale Variable in Auto und durch das Attribut
                        * private außerhalb der Klasse unsichtbar. Zuweisungen
                        * der Art myAuto.a = 5; sind nicht möglich. Die Variable
                        * wird nicht mitvererbt.
                        */
  
  public int b = 2;    /* b ist globale Variable in Auto und durch das Attribut
                        * public von überall zu erreichen. Instanzen der Klasse
                        * akzeptieren Zuweisungen der Art myAuto.b = 8;
                        */
  
  protected int c = 3; /* c ist globale Variable in Auto. Durch das Attribut
                        * protected wird die Sichtbarkeit auf derselben package
                        * beschränkt. Die Variable wird an Ableitungen von Auto
                        * vererbt.
                        */
  
  
  public int getNumber(int x) {
    
    int a = 4;         /* a ist lokale Variable in getNumber() und verdeckt
                        * innerhalb von getNumber() die globale Variable a
                        */
    
    if (x < 10) return a; // Gibt 4 zurück
    
    if (x > 20) return b; // Gibt 2 zurück. (Die globale Variable ist
                          // überall in Auto gültig 
    
    return this.a;        // Gibt 1 aus. (durch das Schlüsselwort
                          // this wird die globale Variable a
                          // angesprochen
  }
  
  private String getPolicy() {
    return ("Diese Methode kann nur innerhalb von Auto verwendet werden. " +
            "Sie wird nicht mitvererbt.");
  }
  
  protected String getLiberalPolicy() {
    return ("Diese Methode kann innerhalb von Auto und von allen Klassen aus " +
            "der Package fahrzeuge verwendet werden. " +
            "Sie wird an abgeleitete Klassen vererbt.");
  }
  
}
    

Weitere Atribute in Java sind static, final und die (eher speziellen und daher hier nicht näher beschriebenen) Attribute transient und volatile.

static
Das Schlüsselwort static ist auf Variablen und Methoden anwendbar. Ist eine Variable oder Methode mit dem Attribut static belegt, so existiert sie für sämtliche Instanzen der Klasse zuammen nur einmal. Statische Variablen sind sogenannte Klassenvariablen. Ändert eine Klasse eine statische Variable, so ist sie auch für alle anderen Instanzen geändert.
Da statische Variablen und Methoden keiner bestimmten Instanz angehören, können sie auch direkt über den Klassennamen erreicht werden, ohne dass erst eine Instanz der Klasse erstellt werden müsste.

final
Das Schlüsselwort final ist auf Variablen, Methoden und Klassen anwendbar.

Da Elemente, die mit dem Attribut final nicht änderbar sind, kann die Virtual Machine zur Laufzeit auf erneutes Laden von Variablen bzw. auf dynamische Methodensuche verzichten, weshalb finale Elemente oft deutlich performanter bearbeitet werden können.

Geheimnisprinzip

([principle of] information hiding) bezeichnet nach [Parnas '72] ein Entwurfsprinzip für Module. Module sollen ihre konkrete Implementierung verbergen. ("Jedes Modul hat ein Geheimnis!")
Komponenten eines Softwaresystems werden als Black Boxes betrachtet, die nur relevante Informationen nach außen zeigen. In Java wird das Geheimnisprinzip insbesondere über Interfaces sowie die Attribute private und protected realisiert.
Vorteile liegen in der konsequenten Modularisierung: Austauschbarkeit der Implementierung einer Klasse (bei Beibehaltung des Interfaces).
Das Geheimnisprinzip ist auch für → Abstrakte Datentypen von Bedeutung.

Polymorphie

Polymorphie (lat. für Vielgestaltigkeit) bezeichnet Eigenschaft einer Variablen, für Objekte verschiedener Klassen stehen zu können. Es gibt verschiedene Arten von Polymorphie:

Assertions

Assertions (Zusicherungen) dienen zur Überprüfung von Invarianten, um Programme robuster zu machen. Dazu wird das Programm mit dem Schlüsslwort assert (ab Java 1.4) angewiesen, eine Bedingung auf Wahrheit zu überprüfen. Trifft diese (i.d.R. wider Erwarten) nicht zu, wird eine Exception ausgelöst. Der Compiler kann über Parameter angewiesen werden, die Zusicherungen an- oder abzustellen, so dass diese z.B. nur während der Entwicklung genutzt werden und für die endgültige Fassung eines Programms zur Laufzeitoptimierung wegfallen.

Parameterübergabe: Call by value vs. Call by reference

Call by value

Der Parameter einer Methode entspricht eriner lokalen Variable, die bei Aufruf mit dem übergebenen Wert initialisiert wird (Parameter-Kopie). Ändert eine Methode den Parameter, so betrifft dies nur ihre lokale Kopie, nicht die übergebene Variable. In Java werden alle primitiven Datentypen per Call by value übergeben.

Call by reference

Paramter werden als Verweis auf eine Variable übergeben. Ändert eine Methode den Parameter, so ist auch die übergebene Variable geändert. In Java werden Objekte als Zeiger übergeben, so dass Änderungen immer global gelten.

Call by result

(Teilw. auch call-by-value-return, u.a. auch bei Schweppe.) Hier wird zunächst das Ergebnis berechnet, und dann in Parameter-Variablen zurückgegeben.

Beispiel (kein Java!):

void solve(in float p, in float q, out float x1, out float x2)
{
  float root = sqrt(p*p/4 - q);
  x1 = -p/2 + root;
  x2 = -p/2 - root;
}
    

Call by name

Entspricht lazy evaluation wie z.B. in Haskell. Vom Ergebnis so wie Call by reference, allerdings mit anderer Semantik: Der übergebene Bezeichner ersetzt beim Aufruf den Parameter der Methodendeklaration, also so ähnlich wie Makros in C. So eine Art automatisches Copy'n'Paste. Die Sprache ALGOL verwendet dieses System, das bei modernen Sprachen kaum noch Anwendung findet. (s.a. FOLDOC: call-by-name)

Entwurfsmuster

Entwurfsmuster (engl. Design Patterns) sind - in der Softwaretechnik - Lösungen für häufig auftretende Problemtypen im Programmdesign. Durch die Verwendung von Entwurfsmustern soll der Code robuster, eleganter und schneller werden, da man das Rad nicht immer neu erfindet, sondern stattdessen erprobte Lösungen verwendet. (Das Problem liegt also eher darin, die passende Lösung aus den bekannten herauszusuchen.)

Häufig verwendete Entwurfsmuster

Datenstrukturen & Implementierungen

Links

Java ist auch eine Insel
Bemerkungen zu den (derzeitigen) Defiziten, z.B. Generics