Die Information, was eine Zahl in einem Term ausmacht, wird in der objektorientierten Modellierung in einer "Klasse" definiert. Halten wir noch einmal fest, aus was die Klassen "Zahl" und "Variable" bestehen:
Die Klasse Zahl enthält:
- einen Wert, der die Größe der Zahl bestimmt.
- eine Möglichkeit die Zahl in Kommaschreibweise darzustellen.
- eine Möglichkeit den Wert der Zahl zu bekommen und weiterzuverwenden.
und hier die Beschreibung einer Variablen:
Die Klasse Variable enthält:
- einen Buchstaben, der die Variable identifiziert.
- eine Möglichkeit den Buchstaben darzustellen.
- eine Möglichkeit den Wert des Buchstabens zu bestimmen und weiterzuverwenden.
Vieles an den Beschreibungen der zwei Klassen ist sehr ähnlich.
Im ersten Fall handelt es sich jeweils um ein Attribut der Klasse (es muss etwas gespeichert werden), während es in den anderen beiden um eine Form der Verarbeitung geht.
Eine Klasse spielt im OOM (objektorientierte Modellierung) die zentrale Rolle, denn sie definiert eine bestimmte Spezies von Objekten. In unserem Fall beschreiben wir mit ihr die Zahlenobjekte und die Variablenobjekte.
Die Definition einer Klasse besteht immer aus drei Elementen:
- Dem Klassennamen
- den Klassenattributen
- den Klassenmethoden
Attribute sind Informationen die mit jedem Objekt dieser Klasse gespeichert sein müssen und Methoden sind Prozeduren, die dieses Objekt ausführen kann. Beides zusammen nennt man die "Eigenschaften" eines Objektes.
Aufgaben
- Überlegen Sie sich eine grobe Klassendefinition für eine Klasse "Auto"
- Überlegen Sie sich eine grobe Klassendefinition für eine Klasse "Fisch"
Hier die Definition der Klasse Zahl in Java. Dabei ist folgendes zu beachten:
Die Methode berechne_wert macht hier eigentlich keinen Sinn, denn es wird eine Belegung übergeben und anschließend wird doch nur der Wert der Zahl zurückgegeben. Diese Methode wird nur verwendet, weil jeder Term diese Eigenschaft haben muss, dass er auf eine Belegung eine Zahl zurückgibt.
class Zahl{ // Definition und Klassenname
public double wert; // Attribut
public double berechne_wert( double belegung[]){ // Methode
return wert; // zur Berechnung des Wertes
}
public String als_text(){ // Methode
return Double.toString( wert ); // zur Darstellung als Zeichenkette
}
}
Bei Attributen handelt es sich um Variablendefinitionen, wie sie schon in der Definition von Unterprogrammen verwendet wurden.
Auch Methoden sind hier nichts anderes als Unterprogramme, die innerhalb des Klassenrumpfes definiert werden. Die Methode zur Wertberechnung einer Zahl braucht zwar die Daten zur Belegung nicht, (denn der Wert ist ja konstant), da aber auch die Zahl ein Term ist wird sie hier wie alle Terme behandelt.
Wie verwendet man jetzt diese Klasse? Betrachten Sie den folgenden Quelltext:
public static void main ( String args[] ){
Zahl x = new Zahl();
System.out.println( "Der Wert des Zahlenobjektes ist "+x.wert );
}
Die Zeilen im einzelnen:
Zahl x = new Zahl();
Hier wird ein Objekt der Klasse Zahl erzeugt, und der Variablen x zugewiesen. Wichtig ist hier der Unterschied zwischen Klasse und Objekt: Während eine Klassendefinition die "Spezies" beschreibt muss noch kein Objekt davon existieren (z.B. weil die Spezies ausgestorben ist!). Erst durch den Befehl new wird ein Objekt im Speicher erzeugt. Damit es auch angesprochen werden kann, wird es mit einem Namen (hier x) versehen.
Nachdem ein Objekt erzeugt wurde, sind alle Attribute zuerst mit Null vorbesetzt. Deshalb ergibt sich durch folgende Quelltextzeile
System.out.println( "Der Wert des Zahlenobjektes ist "+x.wert );
die Ausgabe "Der Wert des Zahlenobjektes ist 0.0". Übrigens sieht man hier auch gleich, wie man sich der Eigenschaften eines Objektes bedient. Mit
x.wert
wird das Attribut "wert" des Objektes x angesprochen. Auf gleiche Weise lassen sich auch Methoden aufrufen:
System.out.println( "Der Wert des Zahlenobjektes ist "+x.berechne_wert() );
Diese Zeile führt zur gleichen Ausgabe wie oben, die zwei Klammern "()" hinter berechne_wert deuten aber an, dass in diesem Fall ein Unterprogramm aufgerufen wurde.
Aufgabe:
- Ändern Sie das bestehende Hauptprogramm so ab, dass die Repräsentation der Zahl als Zeichenkette ausgegeben wird.
Die Klassendefinition der Variable ist der von Zahl sehr ähnlich:
class Variable{
public Character buchstabe;
public double berechne_wert( double belegung[] ){
int pos = buchstabe.compareTo( new Character( 'a' ) ); // alphab. Position
return belegung[pos]; // Belegung, die "buchstabe" entspricht
}
public String als_text(){
return buchstabe.toString();
}
}
Aufgabe:
Mit den bisherigen Mitteln wird ein neues Zahlobjekt erzeugt und anschließend initialisiert. Außerdem kann jeder auf dessen Attribut wert zugreifen (ist als public deklariert).
Im nächsten Schritt werden diese kleinen Schönheitsfehler beseitigt. Wie man in der Zeile:
Zahl x = new Zahl();
an den Klammern hinter Zahl erkennen kann, wird eine Methode aufgerufen, während das Objekt erzeugt wird. Diese Methode heißt Konstruktor und kann von uns neu definiert werden:
class Zahl{
public Zahl( double startwert ){
wert = startwert;
}
...
}
Der Vorteil daran ist, dass schon bei Konstruktion des Objektes die Initialisierung stattfinden kann. Beispiel:
public static void main ( String args[] ){
Zahl x = new Zahl( 3.1 );
System.out.println( "Der Wert des Zahlenobjektes ist "+x.als_text() );
}
Insbesondere ist es nicht mehr nötig, direkt auf das Attribut wert zuzugreifen. Deshalb kann es als private deklariert werden und ist vor Zugriffen geschützt.
Aufgabe:
- Schreiben Sie die Klasse "Variable" entsprechend um.
-
Welche Ausgabe wird durch den folgenden Quelltext erzeugt?
Variable v1 = new Variable( 'a' );
Variable v2 = new Variable( 'b' );
Variable v3 = new Variable( 'c' );
for (int i=0; i<5; i++){
double belegung1[] = {i, i-5, i*2};
System.out.println( v1.als_text()+"="+v1.berechne_wert( belegung1 )+"; "+
v2.als_text()+"="+v2.berechne_wert( belegung1 )+"; "+
v3.als_text()+"="+v3.berechne_wert( belegung1 )+"; "
);
}