In dieser Klassenstufe sind aus der 9.Klasse die Grundprinzipien der funktionalen Modellierung und der statischen Datenmodellierung bekannt (siehe auch Klasse 9). Mit Hilfe der Ablaufmodellierung durch Algorithmen, Zustandsdiagrammen und Sequenzdiagrammen ergänzen wir die Modellierungstechniken und führen sie in der objektorientierten Modellierung zusammen. Die objektorientierte Klasse mit ihren Attributen und Methoden dient bei der Umsetzung (Implementierung) in einer konkreten (objektorientierten) Programmiersprache als Konstruktionsplan. Der Lehrplan wird themenzentriert anhand von konkreten Beispielen umgesetzt. Rumbaugh u.a. haben in ihrem Buch Objektorientiertes Modellieren und Entwerfen die Zielsetzungen der Modellierungsarten treffend in folgendem Satz formuliert: "Das funktionale Modell spezifiziert, was geschieht, das ablauforientierte Modell spezifiziert, wann etwas geschieht, und das Objektmodell spezifiziert, in Bezug auf wen oder was etwas geschieht."
Unter einer Programmiersprache verstehen wir die Schnittstelle zur Kommunikation zwischen Mensch und Computer. In einer Programmiersprache werden Programme für den Computer erstellt, die es erlauben, den Computer Abläufe durchführen zu lassen. Diese Programme werden üblicherweise in einer höheren (plattformunabhängigen) Programmiersprache geschrieben. Ein Compiler (Übersetzer) übersetzt diese Programme dann in Maschinencode. Es gibt viele verschiedene Ansätze für Programmiersprachen. Man unterteilt die Programmiersprachen meist in funktionale Programmiersprachen wie LISP oder Miranda, logische Programmiersprachen wie PROLOG, imperative Programmiersprachen wie C, Pascal, FORTRAN, MODULA und objektorientierte Programmiersprachen wie Java, Oberon, SmallTalk und C++. Es gibt natürlich auch kombinierte Programmiersprachen wie z.B. die funktional-logische Programmiersprache Babel. Wir beschäftigen uns im Unterricht mit der objektorientierten Programmiersprache Java, die wir in der Entwicklungsumgebung BlueJ betrachten. Die Entscheidung für Java erfolgte aus praktischen Gründen, da sie relativ weit verbreitet ist und die Programmierumgebung BlueJ auch für Anfänger geeignet ist. Vom formalen Konzept betrachtet wäre Oberon sicher die erste Wahl unter den objektorientierten Sprachen.
Bitte beachtet, dass ich nur den Teil der Sprache Java beschreibe, den wir im Unterricht besprochen
haben (und das meist an Beispielen). Mir ist bewusst, dass die Beschreibung der Syntax der Sprache Java formal korrekt in der
EBNF-Notation oder mit Hilfe
von Syntaxdiagrammen erfolgen sollte, aber eine solche Darstellung würde die meisten Schüler
unserer 10. Klassen überfordern.
Bei Java wird zwischen Groß- und
Kleinschreibung unterschieden.
Die Programmiersprache Java kennt verschiedene Schlüsselwörter, die an verschiedenen Stellen eines Programms auftreten können. Ihre Schreibweise ist eindeutig festgelegt. Im Unterricht werden wir nur eine Auswahl dieser Schlüsselwörter kennenlernen. Die Schüsselwörter von Java, die wir in der 10. Klasse verwenden, sind fett gedruckt:
abstract assert boolean break byte case catch char class const continue default do double else enum extends final finally float for goto if implements import instanceof int interface long native new package private protected public return short static strictfp super switch synchronized this throw throws transient try void volatile whileBezeichner, also Namen von Klassen, Methoden oder Variablen, die wir selber definieren, dürfen keine Schlüsselwörter sein, d.h. es ist z.B. nicht zulässig, eine Methode abstract zu nennen.
|
TEST |
---|
int zahl TEST() void nachfolger() |
Einzelheiten zu der Java-Klasse TEST:
In der Programmzeile int zahl; steht int hierbei für den Datentyp Integer, also für die Menge der ganzen Zahlen. Die Programmzeile deklariert die Variable (das Attribut) zahl als ganze Zahl, d.h. dieser Variablen dürfen nur ganze Zahlen zugewiesen werden. Beim Übersetzen eines Programms wird eine Symboltabelle (unsichtbar für den Benutzer des Programms) erstellt, in der alle Bezeichner mit ihren Datentypen eingetragen werden. Diese Vorgehensweise dient dazu, Programmfehler aufzudecken.
Die Programmzeile void nachfolger() leitet eine Methodendefinition ein und wird Methodenkopf genannt. Das Schlüsselwort void steht dabei für die Tatsache, dass diese Methode keinen Wert zurückliefert, sondern den Zustand des Objekts, für das diese Methode aufgerufen wird, verändert. Solche Methoden werden auch Setzmethoden oder (bei imperativen Programmiersprachen) Prozeduren genannt.Bemerkenswert ist die Programmzeile zahl = zahl +1; : hier handelt es sich natürlich nicht um eine mathematische Gleichung, sondern um eine Anweisung. Zuerst wird die rechte Seite dieser Anweisung ausgewertet, indem der für die Variable zahl hinterlegte Wert ermittelt wird. Zu diesem Wert wird 1 addiert und dieser neue Wert wird für das Attribut zahl eingetragen. Bei Anweisungen müssen die Datentypen der Ausdrücke beider Seiten übereinstimmen (oder zumindest kompatibel sein), sonst endet eine Übersetzung des Programms mit einem Kompilierungsfehler (meist wird eine Meldung wie incompatible types ausgegeben).
Man unterscheidet in Java zwischen Methoden, die ein Objekt eines Datentyps zurückgeben (sogenannte Funktionen), und Methoden, die keine Rückgabe liefern. Eine Methode besteht aus einem Methodenkopf und einem Methodenrumpf. Methoden, die einen Rückgabewert liefern, enthalten in ihrem Rumpf eine mit return eingeleitete Anweisung. Im unteren Programmstück stehen zwei Methoden, die Rückgabewerte liefern. Die Methode berechneQuadrat erwartet einen Eingabeparameter vom Datentyp double und liefert einen Rückgabewert vom Datentyp double. Ein korrekter Aufruf dieser Methode wäre zum Beispiel berechneQuadrat(5), als Rückgabewerte w&uurde dieser Aufruf 25 liefern.
Die Methode berechneQuadrat() habe ich auch in diese Seite eingebunden (allerdings als JavaScript, die Syntax ist natürlich anders), dann könnt ihr Euch noch etwas mehr Quadratzahlen berechnen lassen:
|
Eine bedingte Anweisung wird in Java mit dem Schlüsselwort if eingeleitet, danach folgt eine in runden Klammern stehende Bedingung (das kann eine einzelne Aussage oder eine Verknüpfung von Aussagen sein, siehe Bedingung) und ein mit geschweiften Klammern umschlossener Anweisungsblock, der nur dann ausgeführt wird, wenn die Bedingung gilt bzw. anders formuliert, wenn die Aussage mit wahr bewertet wird. Die Bedingung wird durch runde Klammern eingeschlossen. Ein optionaler else-Teil, eingeleitet durch das Schlüsselwort else und gefolgt von einem mit geschweiften Klammern umschlossenen Anweisungsblock legt fest, welche Anweisungen ausgeführt werden, wenn die Bedingung mit falsch bewertet wurde. Beispiel:
|
|
|
FELD ist eine spezielle Klasse, deren Objekte mehrere Werte des gleichen Typs zu einer Einheit zusammenfassen. Ein Feld kann so die enthält-Beziehung der Kardinalität 1:n realisieren. Die einzelnen Feldelemente sind durchnummeriert; in vielen Programmiersprachen wie zum Beispiel in Java beginnt die Nummerierung bei 0. Solche Nummern nennt man (Feld-)Index.
Das hört sich natürlich sehr theoretisch an, deswegen schauen wir uns ein Feld jetzt an einem Beispiel an. Nehmen wir an, wir wollen unsere Meerschweinchen verwalten. Wir haben schon gelernt, dass wir ein Meerschweinchen als Objekt der Klasse MEERSCHWEINCHEN modellieren können (siehe Modellierung). Wir ergänzen die Attribute noch um ein Attribut gewicht, damit wir für unser Beispiel ein paar schöne Methoden zeigen können. Die objektorientierte Klasse MEERSCHWEINCHEN lässt sich im erweiterten Klassendiagramm wie folgt darstellen:MEERSCHWEINCHEN |
---|
String name String geburtsdatum String rasse String farbe int gewicht MEERSCHWEINCHEN() void Zeichne() String GibName() void SetzeGewicht(int gewichtNeu) |
MEERSCHWEINCHEN [] herde;schreiben. Damit legen wir fest, dass unser Attribut
herdeein Objekt der Klasse FELD (das wird durch die eckigen Klammern ausgedrückt) ist, dessen Feldelemente Objekte der Klasse MEERSCHWEINCHEN sein werden. Damit könnte unser Klassendiagramm für HERDE wie folgt aussehen:
HERDE |
---|
MEERSCHWEINCHEN [] herde HERDE() void ZeichneAlle() void TrageEin(String name, String geburtsdatum, int gewicht, String rasse, String farbe) void Loesche(String name) void SetzeGewicht(String name, int gewichtNeu) int GibAnzahl() |
|
Fortsetzung folgt!
Die Methode System.out.println ist eine Standardfunktion in Java und muss nicht speziell importiert werden. Sie gibt die Zeichenkette, die sie als Parameter bekommt in ein Konsolenfenster aus. Java verfolgt die call-by-value Auswertungsstrategie bei Parametern, wertet also zuerst den Ausdruck in der Klammer aus. Als Parameter ist deswegen eine in doppelte Hochkommata geklammerte Aneinanderreihung von beliebigen Zeichen möglich und eine Verkettung von Zeichenketten mit Hilfe des "+"-Operators. Wenn eine Zeichenkette mit dem "+"-Operator mit einer Variablen (ohne Hochkommata!) verkettet wird, deren Datentyp eine Zahl ist, dann wird die Zeichenkette mit der textuellen Ausgabe der entsprechenden Zahl verkettet.
1. Beispiel: Die Methodenaufrufe System.out.println("Das ist ein Test"); und System.out.println("Das " + "ist " + "ein " + "Test"); liefern die selbe Ausgabe in dem Konsolenfenster (bei der zweiten Version die Blanks/Leerzeichen nicht vergessen!).Die Namen, die der Programmierer seinen Methoden, Attributen und Variablen gibt, nennt man Bezeichner (identifier). Ein Bezeichner muss mit einem Buchstaben beginnen, dann kann eine beliebige Aneinanderreihung von Buchstaben, Ziffern und Unterstrichen folgen. Schlüsselwörter können nicht als Bezeichner verwendet werden. Auch die drei konstanten Werte (Literale) true, false und null dürfen nicht als Bezeichner verwendet werden. Mögliche Bezeichner wären z.B. zaehler, v_x, zufall_1, ...
Tipps zum Programmierstil:
Aus Rücksicht auf andere Sprachkreise sollten Umlaute, "ß" und andere Exoten nicht in einem Bezeichner
vorkommen. Bezeichner sollten sinnvoll gewählt werden, das erhöht die Lesbarkeit eines
Quellcodes deutlich. Die Namen vordefinierter Klassen wie z.B. Object, String, System sollten ebenfalls nicht
als Bezeichner gewählt werden.