Kapitel 1 Der objektorientierte Ansatz

Werbung
Kapitel 1
Der objektorientierte Ansatz
Programme unterstützen uns im täglichen Leben in fast allen Bereichen. Ob es die
programmgesteuerte Waschmaschine oder das Handy mit Internet-Zugang, die
Kasse im Supermarkt oder die Verwaltung von Adresslisten auf einem elektronischen Assistenten, das Erstellen und Anzeigen von Bildern und ganzen Filmen
oder der Autopilot im Flugzeug ist, Programme werden eingesetzt, um Probleme
zu lösen oder Aufgaben zu erfüllen.
Ein Programm steuert, regelt und verwaltet. Dazu verwendet es Modelle realer Objekte, stellt sie dar, überträgt sie, vermittelt zwischen unterschiedlichen Anwendungen.
Ein Versuch diese unterschiedlichen Aspekte in einem Satz zusammenzufassen,
führt zu folgender Aussage:
Die Ausführung eines Programms ist die Simulation eines Modells der realen oder einer imaginären Welt.
Programmieren bedeutet demzufolge die Modellierung einer Situation und die Umsetzung des Modells in ein ausführbares Programm.
Der Weg von einem Problem zu einem lauffähigen Programm gliedert sich in mehrere Phasen, die durchaus verschiedener Natur sein können und an deren letzter
Stelle erst die eigentliche Programmierung steht.
Wir unterscheiden drei Hauptphasen:
1. Analyse des Problems,
2. Programmentwurf und
3. Implementierung in einer Programmiersprache
Wir betonen in diesem Tutorial natürlich den letzten Punkt, werden aber stets darauf bedacht sein, auch Modellierungsfragen zu besprechen, weil in zutreffender
Analyse und geschicktem Entwurf der Schlüssel zum erfolgreichen Programm
liegt.
Die Terminologie, in der man das Problem analysiert, die also aus dem Anwendungsbereich stammt und noch mehr die, in der man das Programm entwirft, spiegelt sich im objektorientierten Fall oft direkt in der Programmiersprache wider.
2
Kapitel 1: Der objektorientierte Ansatz
Man kommt relativ schnell zu ausführbaren Prototypen, die dann erst nach und
nach zum endgültigen Programm verfeinert werden. Je mehr Begriffe aus der Welt
des Anwenders, der das Problem gestellt hat und das Programm später benutzen
will, verwendet werden, umso leichter wird der Dialog zwischen Programmierer
und Anwender. Das entbindet natürlich nicht von der notwendigen mathematischen
oder strukturellen Aufbereitung des Modells.
Objektorientierter Entwurf und Programmierung verwenden Konzepte wie
das Vergeben von Aufträgen, das Verbergen von überflüssiger Detailinformation und die Interaktion eigenständiger "Wesen". Die Ausdrucks- und
Denkweise aus dem Bereich der Anwendung lassen sich besser als bei der
traditionellen Programmierung in das Programm übertragen.
1.1 Ein einführendes Beispiel
Beispiel 1: Unterhaltungselektronik
Unsere Freizeitbeschäftigung wird heute mehr und mehr von unterschiedlichen
elektronischen Geräten bestimmt. Computerspiele, Audio-CDs, Musikkassetten
(MCs) usw. sind in fast jedem Haushalt zu finden. Etwas Ordnung in diese
Vielfalt zu bringen soll unser Ziel sein. Beschränken wir uns auf einen kleinen
Ausschnitt:
Ein Walkman spielt eine Kassette ab. Dass er dazu immer gehen muss, ist sein
Problem. Bequemer hat es der Discman, der natürlich Audio-CDs erklingen
lässt. Noch nicht ganz erwachsen ist hingegen der Gameboy für Computerspiele.
Objekte sind aktiv
Wir unterscheiden also zwischen aktiven Objekten (Männern und Jungen), die etwas tun, und passiven Objekten (CDs, MCs und Spiele), die unterschiedliche Inhalte darstellen. Diese Unterscheidung ist ganz hilfreich, aber letztlich können auch
die passiven Medien künstlich aktiviert werden, indem sie etwa mitzählen, wie oft
sie schon aufgelegt wurden oder zumindest Auskunft darüber geben, welches Gerät
sie benötigen. So kommen wir der weit verbreiteten Sicht eines objektorientierten
Programms als eine Menge kommunizierender Objekte schon nahe. Ein Discman
erhält eine CD und spielt diese ab. Er reagiert darauf durch seine ihm angemessene
Verhaltensweise. Die Objekte können also agieren, sie kennen gewisse Methoden,
die ihr Verhalten bestimmen. Diese Methoden sind allen gleichartigen Objekten zu
eigen, alle Audio-CDs können von einem Discman gespielt werden, jedoch nicht
von einem Walkman.
1.1 Ein einführendes Beispiel
3
Objekte gehören zu Klassen
Jedes Objekt wird als ein Exemplar einer Klasse aufgefasst, jede CD ist ein individuelles Exemplar der Klasse aller CDs. Neben den Methoden verfügen die Objekte einer Klasse auch über gemeinsame Attribute, die ihren Zustand beschreiben, z.B. kann eine CD noch original verpackt, noch nie gespielt oder schon oft gehört sein. Dieser Zustand eines Objektes beeinflusst die Verhaltensweise, indem
abhängig von seinem Wert gewisse Methoden aufgerufen werden können, oder andere unterschiedlich reagieren. Eine Klasse legt also nicht nur Methoden fest, sondern auch Eigenschaften oder Attribute, deren Werte für jedes individuelle Objekt
verschieden sein können. Objekte haben eine Identität, auch solche mit identischen Attributwerten können unterschieden werden.
Objekte werden im Verlauf eines Programms geschaffen, konstruiert. Bei der Konstruktion werden einige Attribute gesetzt, andere kommen während des Programmlaufs hinzu. Normalerweise kann der Wert eines Attributes verändert werden.
Beziehungen
Objekte stehen in Beziehungen zueinander. Wenn wir für eine Klasse ein rechteckiges Bild wählen, in dem der Klassenname, die Attribute und die Methoden aufgeführt sind, so lässt sich folgendes Diagramm (UML Klassendiagramm) zeichnen.
Abbildung 1: Beziehungen zwischen Klassen
Auch Objekte werden durch ein Rechteck dargestellt, auf welches ein mit dem Objektnamen bezeichneter Pfeil verweist. Das Szenario, dass eine Karajan CD, ein
Exemplar der Klasse CD, dessen Attribut interpret den Wert "Karajan" besitzt, auf einem Discman der Marke Headache und eine Kassette von Queen
gleichzeitig auf einem Walkman der Marke Marathon laufen, wird durch folgendes Bild veranschaulicht.
4
Kapitel 1: Der objektorientierte Ansatz
Abbildung 2: Beziehungen zwischen Objekten
1.1.1 Aktive Objekte
Ganz wichtig im objektorientierten Programmieren ist die Idee, dass alle Aktivität
von Objekten ausgeht. Im angeführten Beispiel mit der Unterhaltungselektronik
lässt sich das noch relativ gut nachvollziehen.
Beispiel 2: aktive Objekte
Im obigen Bild spielt ein Discman mit dem Namen discy die CD mit dem
Namen cd1.
Das lässt sich unmittelbar als Java Fragment schreiben.
discy.spiele(cd1);
1.1.2 Klassifikation
Die Klassifikation der Objekte in verschiedene Klassen, kann noch weiter getrieben werden. So lassen sich CDs und MCs zum Oberbegriff Musikmedium zusammen fassen. Auch die Tatsache, dass beide gleich lautende Attribute besitzen, regt
zu dieser Verallgemeinerung an.
1.1 Ein einführendes Beispiel
5
Abbildung 3: Klassifikation von Musikmedium
Dieses Bild sollte wie folgt gelesen werden: Jede CD und jede MC ist ein Musikmedium und hat deshalb ein Attribut, welches den Interpret bezeichnet. Eine MC
kann gelöscht werden, eine CD nicht. Diese Ist-ein Beziehung bezeichnet man im
objektorientierten Programmieren als Vererbung1 Eine MC hat und kann alles, was
ein Musikmedium kann und bietet darüber hinaus noch die Methode istLeer()
an.
Ebenso gehören alle Abspielgeräte zu einer Klasse, Kategorie oder Hierarchie. Jedes Gerät besitzt ein Attribut, welches den Firmennamen repräsentiert und eine
Abspielmethode. Die wird allerdings erst dann festgelegt, falls klar ist, um was für
ein Gerät es sich handelt. Es ist also nicht sinnvoll Objekte der Klasse Gerät anzulegen, denn wir wissen nicht wie das Abspielen funktioniert. Die Klasse Gerät ist
abstrakt2. Trotzdem ist es möglich und sinnvoll etwa eine Liste verschiedener Geräte zu verwalten, von denen jedes eine spezifische Abspielmethode besitzt. Jedes
Gerät verhält sich also seinem Typ gemäß3.
Abbildung 4: Klassifikation von Geräten
1
Siehe auch: Vererbung (S. 173)
Siehe auch: Abstrakte Klassen (S. 194)
3
Siehe auch: Polymorphie (S. 189)
2
6
Kapitel 1: Der objektorientierte Ansatz
1.1.3 Datenkapselung
Ein weiteres Merkmal der objektorientierten Vorgehensweise ist die konsequente
Umsetzung der Datenkapselung. Darunter versteht das Verbergen von unnötigen
Detailinformationen. So ist es für den Aufruf einer Methode nicht wichtig, die Implementierung genau zu kennen. Die Wartbarkeit und Lesbarkeit eines Programms
wird erhöht, wenn für das Ändern von Attributen Zugriffsrechte vergeben werden.
Am einfachsten ist die Regel, dass im Sinne der Eigenverantwortung der Objekte,
Attributwerte nur von dem Objekt selbst verändert werden sollten.
Die Attribute interpret und marke sollten in unserem Beispiel nur bei der
Konstruktion gesetzt werden. Wenn ein Computerspiel hingegen mitzählen soll,
wie oft es bereits aufgerufen wurde, so ist ein schreibender Zugriff auf das Attribut
anzahl eigentlich nur im Zusammenhang mit dem Abspielen erwünscht. Das Attribut wird gekapselt.
1.2 OOP im Überblick
Wir stellen die wesentlichen Aspekte des objektorientierten Ansatzes zusammen:
• Objekte sind eigenständige Einheiten die einen Zustand haben.
• Der Zustand wird bestimmt durch die Werte der Attribute und wird nur
durch das Objekt selbst verändert.
• Objekte werden von anderen Objekten durch Botschaften zur Ausführung
von Zustandsänderungen angeregt.
• Objekte sind Exemplare einer Klasse, die gemeinsame Attribute und Aktionen zusammenfasst.
• Die genaue Datenstruktur und die Wirkungsweise der Methoden sind gekapselt.
• Klassen stehen in Beziehung zueinander, es gibt Unterklassen und Oberklassen.
• Eine Unterklasse unterscheidet sich von ihrer Oberklasse dadurch, dass sie
mehr Merkmale aufweist, also eine Spezialisierung und damit eine Teilmenge beschreibt.
• Die Unterklasse übernimmt oder erbt alle Attribute und Methoden der
Oberklasse.
• Sie kann die ererbten Methoden modifizieren und neue definieren.
• Es gibt abstrakte Klassen, von denen keine Objekte ausgeprägt werden können.
• Ein Objekt reagiert entsprechend seinem zur Laufzeit festgelegten Typ.
Die Vererbung von Methoden und Attributen ist ein wesentliches Merkmal von
objektorientierter Programmierung.
1.3 Programmaufbau
7
Ein weiteres wichtiges Merkmal ist die Möglichkeit wiederverwendbaren, weiterverwertbaren Programmcode zu erstellen. Dabei kann durch das Klassenkonzept der auf dem Rechner zur Verfügung stehende Vorrat an Datenstrukturen und
Operationen ständig erweitert werden. Es ist in einer gut ausgestatteten Programmierumgebung nicht mehr nötig, das Rad zum x-ten Male neu zu erfinden, sondern
man kann komplexe Strukturen und Operationen wie einfache Standardtypen benutzen. Um bei unserem Beispiel zu bleiben, kann man sagen, dass es nun möglich
ist, ein Gerät aus fertigen Modulen zusammenzusetzen, ohne sich im Einzelnen um
deren Aufbau kümmern zu müssen. Entsprechend vereinfacht sich die Wartung.
Die objektorientierte Programmierung unterstützt sowohl die Anwendung von fertigen Programmbausteinen als auch deren Erstellung. Sie unterstützt modulares
Vorgehen.
1.3 Programmaufbau
Ein objektorientiertes Programm konstruiert (erzeugt) Objekte, die dann miteinander kommunizieren, indem sie eigene Methoden (Handlungsvorschriften) ausführen oder solche anderer Objekte aufrufen. In Java wird dieser Ablauf durch Aufruf
der Methode main der Startklasse angestoßen. Das Programm selbst, der Programmtext oder Quelltext, besteht aus einer Reihe von Klassenvereinbarungen. Eine dieser Klassen, die Startklasse enthält eine Methode main.
Das einfachste Programm ist also eine Klassenvereinbarung, die nur die Methode
main enthält.
Beispiel 3: Programmschablone
public class Schablone {
public static void main(String[] args) {
// Hier wuerden die Anweisungen stehen ...
}
}
cdrom:/buch/examples/java/Aufbau/Schablone.java
Dieses Programm tut nichts. Wir wollen an dieser Stelle die Bedeutung der einzelnen Wörter nicht erklären und fassen dieses Beispiel als feste Schablone auf, in der
der Name der Klasse und der Rumpf der Methode main verändert werden, um ein
neues Programm zu erhalten.
Der Rumpf der Methode main ist hier durch einen Kommentar ersetzt. Kommentare dienen zur Dokumentation und Erläuterung des Quelltextes und werden bei
der Verarbeitung ignoriert. Kommentare können grundsätzlich an allen Stellen im
Quellcode stehen, solange sie dort eindeutig als Kommentare zu identifizieren sind,
also z.B. nicht innerhalb von Zeichenketten oder Namen.
8
Kapitel 1: Der objektorientierte Ansatz
Es gibt drei Arten von Kommentaren:
• Zeilenend-Kommentare: Beginnen mit // und enden am Zeilenende. Sie
werden üblicherweise zum Erläutern von einzelnen Anweisungen verwendet.
• Block-Kommentare: Stehen zwischen /* und */. Sie dienen meist zum
Deaktivieren von Code-Bereichen, und werden selten zur Dokumentation
verwendet.
• Javadoc-Kommentare: Wie Block-Kommentare, beginnen jedoch mit
/**. Sie werden für die aus dem Quellcode automatisch erzeugte Dokumentation verwendet und stehen daher normalerweise vor Konstrukten, die
für die Verwendung des Codes durch andere Programme (oder Programmteile) geeignet sind, wie Klasse, Methoden oder Konstanten. Die JavadocKommentare haben eine interene Struktur, die bei den Quelltext-Konventionen4 beschrieben ist.
Beispiel 4:
Das folgende Programm gibt das Produkt von zwei Zahlen aus:
public class Produkt {
public static void main(String[] args) {
int faktor1 = 2;
int faktor2 = 3;
System.out.println(faktor1 * faktor2);
}
}
cdrom:/buch/examples/java/Aufbau/Produkt.java
Ein einfaches Programm lässt sich durch folgendes Bild veranschaulichen: Wir
zeichnen eine Klasse als ein Rechteck mit drei Fächern. Im ersten steht der Klassenname, im zweiten die Attribute und im dritten die Methoden.
Abbildung 5: Aufbau einer Klasse
Üblicherweise besteht ein Programm aus mehreren Klassen, von denen jede in einer eigenen Datei gespeichert wird.
Beispiel 5: Die Klasse Preis1
Als Beispiel eines einfachen Programms vereinbaren wir eine Klasse, die einen
Preis in Euro und Cent repäsentiert und eine Methode besitzt, die diesen Preis
in Cent ausliest. Eine Testklasse konstruiert ein Preis-Objekt und ruft die Methode auf.
Außerdem gibt es eine Methode, die einen Preis um einen anderen erhöht.
4
Siehe auch: Quelltext-Konventionen (S. 308)
1.3 Programmaufbau
9
Abbildung 6: Die Klasse TestPreis1 verwendet die Klasse Preis1
System.out.println(p1.getPreisInCent());
// p1 wird um einen Preis p2 erhoeht
p1.erhoehe(p2);
System.out.println(p1.getPreisInCent());
cdrom:/buch/examples/java/Klasse/TestPreis1.java
Wir zeigen vom Programm hier nur den Methodenaufruf.
Zusammengehörige Klassen werden in Paketen gruppiert. Der Paketname entspricht dabei einem Verzeichnis- (Ordner-)Namen im Dateisystem.
Abbildung 7: Die Klassen TestPreis1 und Preis1 in einem Paket
Die Beliebtheit und schnelle Verbreitung von Java wurde wesentlich durch eine
Vielzahl vorhandener Standardpakete5 erhöht.
Man kommt eigentlich nicht ohne fremde Pakete aus. So werden wesentliche Teile
der Ein- und Ausgabe oder auch häufig gebrauchte Datentypen in Standardpaketen
zur Verfügung gestellt. Der Import von Standard- oder selbst geschriebenen Paketen ist möglich und geschieht durch Angabe einer import- Klausel. Nur das Paket java.lang, welches die wichtigsten Standardklassen wie z.B. String und
Math enthält, steht ohne Import zur Verfügung.
Wir wollen hier nicht ins Detail6 gehen. Wir weisen jedoch darauf hin, dass wir für
dieses Tutorial ein Paket simple bereit stellen, welches zwei Einzelpakete enthält.
5
6
Siehe auch: Standardpakete (S. 199)
Siehe auch: Import von Paketen (S. 57)
10
Kapitel 1: Der objektorientierte Ansatz
Beispiel 6: Import von Klassen
Wir importieren die Klasse SimpleInput aus dem Paket simple.io und
die Klasse ArrayList aus dem Standardpaket java.util. Zur Veranschaulichung verwenden wir folgendes Bild:
Abbildung 8: Importieren von Klassen
Ein Name für das aktuelle Paket ist nicht notwendig.
1.4 Java verwenden
Java wurde von Sun Microsystems als eine Plattform-unabhängige, überall in gleicher Weise einsetzbare, objektorientierte Sprache entwickelt. Gleichzeitig mit dem
Vorliegen der ersten Sprachdefinition 1995 wurde auch ein Entwicklungssytem
(JDK - Java Development Kit) und eine umfangreiche Sammlung von Paketen oder
Programmbibliotheken zur freien Verfügung gestellt. Diese Tatsache und die Möglichkeit, Programme einfach über das Internet aufzurufen, trugen zusammen mit
dem allgemeinen Vormarsch der Objektorientierung zur rasanten Verbreitung bei.
Da Java eine neue, rein objektorientierte Sprache ist, die auf Erfahrungen zurück
greift, die mit C++ gemacht wurden, können wir Java als eine fortgeschrittene und
fortschrittliche Sprache bezeichnen.
Das aktuelle Java (offiziell Java 2 genannt) unterteilt sich in zwei Komponenten.
Das J2RE - Java 2 Runtime Environment ist für die Ausführung von Programmen
zuständig. Will man also ein Java Programm verwenden, so ist diese Komponente
notwendig und ausreichend.
Darüber hinaus gibt es zu Java noch eine ganze Reihe von Werkzeugen für die Erstellung von Java-Programmen, wie z.B. den Java-Compiler (javac), der den Programm-Quelltext in Bytecode übersetzt, welcher dann vom J2RE verwendet werden kann. Diese Werkzeuge sind selbst teilweise wieder Java-Programme und be-
1.4 Java verwenden
11
nötigen daher zur Ausführung das J2RE. Daher werden die Werkzeuge zusammen
mit dem J2RE als J2SDK - Java 2 Software Development Kit zusammengefasst.
Darüber hinaus gibt es Java noch in unterschiedlichen Varianten für verschiedene
Gruppen von Zielgeräten. Normalerweise verwendet man die J2SE - Java 2 Standard Edition, jedoch stehen z.B. für stark eingeschränkte Endgeräte wie Handys
oder PDAs die J2ME - Java 2 Micro Edition oder für Firmenanwendungen die
J2EE - Java 2 Enterprise Edition zur Verfügung. Wir wollen uns hier lediglich mit
der J2SE befassen, grundsätzlich lassen sich die vorgestellten Konzepte und Verfahren jedoch auch auf die anderen Platformen übertragen.
Auf der beiliegenden CD finden sich auch die aktuelle Version (1.4.2) des
J2SDK für Windows und Linux. Diese und neuere Versionen, wie z.B. die
sich zur Zeit in Vorbereitung befindliche Version 1.5, können auch von der
Java-Homepage7 heruntergeladen werden. Details zur Installation findet man im Anhang8 oder bei Sun9.
1.4.1 Umgebung
Java Programme können in unterschiedlichen Umgebungen erstellt werden. Diese
stellen drei Grundfunktionen zur Verfügung:
• Eingeben bzw. Ändern (Editieren) des Quellcodes,
• Übersetzen (Compilieren) des Quellcodes in Bytecode,
• und Ausführen (Interpretieren) des Bytecodes.
Die einfachste Umgebung ist die direkte Verwendung der mit dem J2SDK gelieferten Werkzeuge, wobei diese den ersten Schritt nicht explizit unterstützen. Das ist
auch nicht nötig, denn zum Bearbeiten des Quellcodes ist generell jeder Editor geeignet. Es ist jedoch von Vorteil, wenn der Editor einen speziellen Modus für Java
besitzt, so dass mindestens automatisches Einrücken und Syntax-Highlighting
(Hervorherben von syntaktischen Elementen z.B. durch Farben) möglich ist.
Das Übersetzen des Quellcodes in Bytecode erfolgt mit dem Programm javac. Javac ist der Compiler des J2SDK. Er übersetzt den Quellcode (z.B. Hello.java)
in den "ausführbaren" Bytecode (Hello.class).
Der erzeugte Bytecode kann dann auf jedem System, für das Java verfügbar ist,
von der Virtuellen Maschine (JVM - Java Virtual Machine) ausgeführt werden. Die
JVM wird mit dem Kommando java gestartet.
Folgender Ablauf beschreibt den typischen Vorgang bei der Erstellung eines JavaProgramms:
7
http://java.sun.com/j2se/downloads.html
Siehe auch: Installation des J2SDK (S. 273)
9
http://java.sun.com/j2se/1.4.2/install.html
8
12
Kapitel 1: Der objektorientierte Ansatz
Abbildung 9: Entwicklungszyklus eine Java Programms
Dieser wird üblicherweise in Zyklen wiederholt, bis das Programm das gewünschte
Ergebnis liefert.
Der Vorteil dieses Verfahrens liegt darin, dass es gleichermaßen auf praktisch allen
Systemen verwendet werden kann, für die ein J2SDK zur Verfügung steht. Weiterhin behält man die volle Kontrolle darüber, was passiert, und kann die Ergebnisse
(und Fehler) direkt beobachten.
Zur Benutzung des fertigen Programm reicht es aus, die .class-Dateien (z.B. als
Archiv) zu verteilen. Diese können dann auf allen Systemen, auf denen eine JVM
zur Verfügung steht, ausgeführt werden.
Details zur Verwendung des Java-Compilers und zum Aufruf der JVM finden sich
wiederum im Anhang10.
Statt des manuellen Aufrufs der Werkzeuge kann man auch sogenannte Integrierte
Entwicklungsumgebungen (IDE - Integrated Development Environment) verwenden. Diese bieten neben herkömmlichen Editorfunktionen zusätzliche Unterstützung wie z.B. eingebaute Hilfe, automatische Vervollständigung, Fehlerkorrektur
und vieles mehr. Das ist zwar prinzipiell ein großer Vorteil, birgt aber gerade für
Einsteiger auch die Gefahr der Informationsüberflutung.
Solche Entwicklungsumgebungen gibt es in großer Zahl sowohl im kommerziellen als auch im Open Source Umfeld. Auf der CD ist die aktuelle
Version von Eclipse für Windows und Linux enthalten.
Es sei noch darauf hingewiesen, dass auch die meisten Entwicklungsumgebungen
das J2SDK benötigen. Sie bringen meist keinen eigenen Compiler oder gar eine eigene JVM mit. Die Installation des J2SDK ist also auch beim Einsatz einer IDE
meist nötig.
Damit die Beispiele dieses Tutorials möglichst einfach ausprobiert werden können,
haben wir ein Programm in die HTML-Version integriert, die es erlaubt die Beispiele direkt zu starten. Das Programm JEEE ermöglicht es die Beispiele auszuführen (mit Benutzerinteraktion, sofern das vom Beispiel vorgesehen ist) oder diese
auch zu verändern. Voraussetzung ist lediglich die Installation des J2SDK.
10
Siehe auch: J2SDK (S. 273)
1.4 Java verwenden
13
Details zum Setup und der Verwendung von JEEE finden sich wiederum im Anhang11.
1.4.2 Syntaxdiagramme
Eine Programmiersprache hat feste syntaktische Regeln. Diese sind meist nicht
einfach durch Text zu beschreiben, und eine formale textuelle Beschreibung ist
nicht gut zu verstehen. Daher verwenden wir Syntaxdiagramme zur Beschreibung. Syntaxdiagramme definieren Schablonen, die durch Ausfüllen zu fertigen
Programmen (oder Programmteilen) führen.
Folgendes Diagramm zeigt einige der wichtigsten Eigenschaften:
Die abgerundeten Elemente sind sogenannte Terminale, die einen festen, exakt so
in das Programm zu übernehmenden Text darstellen. Die eckigen Elemente sind
die Nicht-Terminale, die durch etwas anderes ersetzt werden müssen. Was das genau ist, ist jeweils an anderer Stelle beschrieben, die Bezeichnung gibt aber einen
Hinweis.
Im obigen Bild ist also die "0" ein Terminal, und "1..9" bzw. "0..9" Nicht-Terminale (diese wären dann gemäß einem anderen Syntaxdiagramm durch die entsprechenden Ziffern zu ersetzen).
Syntaxdiagramme werden von links oben, den durchgezogenen Linien folgend,
von links nach recht und von oben nach unten durchlaufen. Gestrichelte Linien
werden in entgegengesetzter Richtung durchlaufen. Kann man an einer Stelle mehreren Wegen folgen, so ist einer davon zu wählen. Erreicht man das Ende der Linie
(ganz rechts) so ist dieses Syntaxdiagramm vollständig durchlaufen.
Bei Durchlaufen des obigen Diagramms beginnt man nun links oben, und muss
sich dann gleich entscheiden. Man kann der Linie nach rechts folgen, dann kommt
man an das Terminal "0". Folgt man der Linie dann weiter, so kommt man unweigerlich an das Ende des Diagramms (an der Kreuzung darf man ja nur nach rechts,
da nur gestrichelte Linien nach links durchlaufen werden). Eine Dezimalzahl kann
also eine einzelne "0" sein.
11
Siehe auch: JEEE (S. 282)
14
Kapitel 1: Der objektorientierte Ansatz
Alternativ kann man anfangs auch der Linie nach unten folgen. Dann kommt man
an das Nicht-Terminal "1..9" welches für eine der Ziffern 1 bis 9 steht. Dannach
kann man der Linie weiter bis ans Ende folgen. D.h. die Ziffern 1 bis 9 sind auch
"Dezimalzahlen". Statt bis an das Ende des Diagramms zu gehen kann man aber
auch die Abzweigung nach unten nehmen. Hier kommt man an das Nicht-Terminal
"0..9". Von dort aus kann man entweder weiter bis an das Ende des Diagramms,
oder man geht nach unten, folgt dann der gestrichelten Linie zunächst nach links
und dann noch oben, und kommt dann wieder zum Nicht-Terminal "0..9" und ist
damit wieder an derselben Stelle wie oben. Man kann also die "Schleife" beliebig
oft durchlaufen. Dies bedeutet also, dass eine Ziffer 1 bis 9, gefolgt von keiner, einer oder beliebig vielen Ziffern 0 bis 9 eine Dezimalzahl darstellt.
Man beachte, dass Zahlen die mit einer "0" beginnen und nicht nur aus diesem einen Zeichen bestehen keine Dezimalzahlen sind. Diese werden als
Oktal- bzw. Hexadezimalzahlen interpretiert.
1.4.3 Das Hilfspaket simple
In Java gibt es verschiedene Wege Daten einzulesen. Diese werden im Abschnitt
Ein-/Ausgabe12 behandelt. Allerdings sind diese Möglichkeiten für die normale
Verwendung vorgesehen und erfordern daher komplexere Vorgänge, insbesondere
z.B die Fehlerbehandlung. Da dies im Moment noch nicht so wichtig für die Programme ist und sie nur unnötig verkompliziert, und damit vom Wesentlichen ablenkt, werden wir in diesem Tutorial eine Hilfsbibliothek verwenden, die es erlaubt, die Eingabe (und einiges andere) vereinfacht vorzunehmen.
Die Bibliothek simple stellt dazu Möglichkeiten zur Verfügung Daten (Zahlen,
Wörter, Zeilen) von der Tastatur einzulesen, oder auch Zufallszahlen zu erzeugen.
Eine genauere Beschreibung der Bibliothek und Details zur Verwendung und zur
Einbindung finden sich im Anhang13. Wenn die Beispiele allerdings mit JEEE über
die HTML-Version des Tutorials gestartet werden, braucht man sich darum erstmal
nicht zu kümmern.
1.5 Gestaltung und Formatierung von Java-Quelltext
In kleinen Programmen mag es egal sein, in welcher Form der Quelltext geschrieben wird, wie weit man z.B. einrückt, wo Kommentare stehen etc., aber in einem
großen und zeitlich ausgedehnteren Projekt ist es wichtig, dass der Programmcode
auch von anderen Programmierern und auch nach Jahren noch leicht lesbar und
nachvollziehbar ist.
12
13
Siehe auch: Ein-/Ausgabe (S. 237)
Siehe auch: Die Bibliothek: simple (S. 284)
1.5 Gestaltung und Formatierung von Java-Quelltext
15
Deshalb halten wir uns an Formatierungsregeln, die in fast allen Punkten der Java
Coding Convention14 von Sun Microsystems entnommen sind.
Im Einzelnen werden wir die Konventionen im Text durch in dieser Weise
gekennzeichnete Absätze einführen.
Die Gestaltungsregeln sind im Anhang15 zusammengefasst.
14
15
http://java.sun.com/docs/codeconv/
Siehe auch: Quelltextkonventionen (S. 307)
http://www.springer.com/978-3-540-23134-9
Herunterladen