Kapitel 3 - Datenstrukturen im objektorientierten Programmieren 3.1 3.2 3.3 3.4 3.5 Algorithmik 1 Variablen einfachen Typs Objekte und Klassen in Java Klassenhierarchien Umsetzung von UML-Klassendiagrammen Andere zusammengesetzte Datentypen Prof. Dr. Michael Philippsen / Prof. Dr. Herbert Stoyan Handy aus! Friedrich-Alexander-Universität Erlangen-Nürnberg Informatik 2/8 Programmiersysteme / Künstliche Intelligenz Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-2 1.5 Programmgesteuerter Rechner (Babbage, 1833) M. Philippsen 1.6 Von-Neumann-Rechner Sedezimale Darstellung „Hex-Dump“ Speicher, konzeptuell Speicher EingabeDaten, Adresse 0 Adresse 4 Verarbeitung ZwischenErgebnisse Zustand Programm Zustandsübergang : Überführung des Inhalts des Speichers (eine oder mehrere Speicherzellen) in einen neuen Inhalt durch Anwendung einer Operation. Zustand: Momentaner Inhalt der Speicherzellen Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-3 0100 0100 0100 0100 0100 0100 0101 0101 0100 1101 0011 0001 1100 1000 1100 0000 0011 1110 0100 0100 0100 0101 0100 0100 0101 0100 1001 1000 0101 0000 1001 1001 0000 0101 4D 43 41 4C 48 4C 50 53 4E 49 48 45 50 49 49 50 45 Nur mit Interpretationsvorschrift ist klar, was die Werte im Speicher bedeuten. Binär codierter Zeichenvorrat, Binärdarstellung von Zahlen aber auch: „Nummern“ von Maschinenbefehlen Æ nicht „benutzerfreundlich“ Aufgabe: Decodierung mit ASCII-Code Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen / H. Stoyan Algorithmik 1, WS 2004/05, Folie 3-4 M. Philippsen 3.1 Variablen einfachen Typs 3.1 Variablen einfachen Typs Eigenschaften einer Speicherzelle: Ablauf des Zugriffs über den Namen: y Sie stellt einen Behälter dar, der über eine Adresse angesprochen wird und einen Inhalt (Wert) aufnimmt. y Wir sagen: „Die Zelle mit Adresse a hat den Wert w zum Inhalt“. Abstraktion für den Programmierer: Die Adresse interessiert nicht. y Verwendung einer die Zelle identifizierenden Zugriffsfunktion: Name. y Ergebnis der Berechnung der Adresse über die Zugriffsfunktion: Referenz. Beispiel: Ausführende Operation: 1/pi Name: pi Addresse: 003 Wert: 3.141 Referenz von pi ist die Addresse 003. Der Wert der Referenz ist 3.141. Anderes übliches Wort für Name: Bezeichner Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-5 y Lesend: Vorgabe des Namens → Beschaffung der Referenz → Zugriff auf den Behälter → Lieferung des Wertes als Ergebnis y Schreibend: Vorgabe des Namens → Beschaffung der Referenz → Zugriff auf den Behälter → Ersetzen des Wertes Variablen sind Namen, die lesenden und schreibenden Zugriff erlauben Konstanten erlauben nur Lesezugriffe Beachte: Der schreibende Zugriff hat einen sogenannten Seiteneffekt, d.i. eine Veränderung des Zustands (im Speicher) des Rechners Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Algorithmik 1, WS 2004/05, Folie 3-6 M. Philippsen 3.1 Variablen einfachen Typs 3.1 Variablen einfachen Typs Ein Name ist eine beliebig lange Folge von „Java-Buchstaben“ und „Java-Ziffern“, beginnend mit einem „Java-Buchstaben“, wobei: Jede Variable oder Konstante besitzt einen Typ. y Java-Ziffer = Zahl zwischen 0 und 9 y Java-Buchstabe: Buchstabe aus dem gesamten sog. UnicodeZeichenvorrat, in dem die meisten auf der Welt verwendeten Schriftzeichen enthalten sind. y Festlegung des gültigen Wertebereichs y Festlegung der anwendbaren Grundoperationen (später mehr) Einfache Typen: Ein Name darf also nicht mit einer Ziffer beginnen. Primitiver Typ Numerischer Typ Beispiele: y gültige Bezeichner: y ungültige Bezeichner: i3, algo_1, MAX_WERT 1algo, 12HUNDERT, 0nixgut Ganzzahliger Typ Gleitkomma-Typ Wichtig: Groß- und Kleinschreibung wird unterschieden. Algo1 und algo1 sind also zwei ganz verschiedene Bezeichner. byte Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-7 char long int short float double boolean Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Algorithmik 1, WS 2004/05, Folie 3-8 M. Philippsen 3.1 Variablen einfachen Typs Basistyp Beschreibung boolean Wahrheitswert 3.1 Variablen einfachen Typs restlicher Text muss exakt wie angegeben im Programm erscheinen. <XXX> ist ein Platzhalter; im Programm zu ersetzen. Wertebereiche true, false Art Syntaktische Form Beispiele byte, short, int, long vorzeichenbehaftete Ganzzahlen von 8, 16, 32, 64 Bit Länge. -27 = -128 ≤ byte ≤ 127 = 27-1 -215 = -32 768 ≤ short ≤ 32 767 = 215-1 -231 = -2 147 483 648 ≤ int ≤ 2 147 483 647 = 231-1 -263 = -9 223 372 036 854 775 808 ≤ long long ≤ 9 223 372 036 854 775 807 = 263-1 unbenannte Konstante (Literal) <Wert> 1, true, 'c' Variablenvereinbarung (Deklaration) <Typ> <Name>; int a; float, double Gleitpunktzahlen von 32 bzw. 64 Bit gemäß IEEE 754-1985. Kleinste float Zahl >0: 1.40239846e-45 Größte float Zahl >0: 3.40282347e+38 Kleinste double Zahl >0: 4.94065645841246544e-324 Größte double Zahl >0: 1.79769313486231570e+308 lesender Zugriff <Name> a + 1 schreibender Zugriff (Zuweisung) <Name> = <Wert>; a = 1; char Einzelzeichen Unicode, 16 Bits, http://www.unicode.org <Wert> kann auch ein zu berechnender Ausdruck sein. Friedrich-Alexander-Universität Erlangen-Nürnberg Initialwert der Variable ist typspezifisch. Meist 0. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-9 M. Philippsen 3.1 Variablen einfachen Typs Algorithmik 1, WS 2004/05, Folie 3-10 M. Philippsen 3.1 Variablen einfachen Typs Wert von a nach der Anweisung Beispiele Art Syntaktische Form Variablenvereinbarung mit Vorbesetzung (Deklaration mit Initialisierung) Vereinbarung einer benannten Konstanten mit Einmaldefinition Beispiele //Deklaration //Initialisierung mit //Literal 1 1 a = a + 1; //Inkrementierung 2 a++; //Inkrementierung 3 <Typ> <Name> = <Wert>; int a = 1; final <Typ> <Name> = <Wert>; final float pi = 3.14159; Der Übersetzer stellt sicher, dass es nur eine Definition im Programm gibt. a; //Lesezugriff final int b = a; //Deklaration //einer Konstanten float c = 1.0f; //float-Literal int d, e = 5; //mehrere Deklarationen //von einem Typ (d=0,e=5) Komma vereinfacht Deklarationsschreibweise Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-11 int a = 1; später: d bleibt als lokale Variable uninitialisiert. Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen / H. Stoyan Algorithmik 1, WS 2004/05, Folie 3-12 3 3 3 3 Folge der Zugriffsfunktion: Es wird immer der (einzig verfügbare) aktuelle Wert M. Philippsen gelesen. 3.2 Objekte und Klassen in Java Objekt als Komponente Schnittstelle („interface“) 3.2 Objekte und Klassen in Java Funktionalität Gegenstand der Anschauung Struktur Operatorsignaturen Dienst Algorithmen und Datenstrukturen Klasse („class“) Objektklasse als KomponentenBaumuster Objekt Ein Objekt besitzt eine eindeutige Identität und einen Zustand, die zugehörige Klasse „enthält“ Code zur Manipulation des Zustands Zustand („state“) y Beschrieben durch einen Verbund von Attributwerten bzw. Daten y Kann sich im Laufe der Zeit ändern Verhalten („behavior“) Attribute Assoziationen Operatorimplementierungen Menge gleichartiger Gegenstände der Anschauung Funktionalität Struktur Friedrich-Alexander-Universität Erlangen-Nürnberg y Beschrieben durch eine Menge von Handlungsvorschriften zur Erbringung eines Dienstes durch ein Objekt (Methode) y Die Ausführung eines Dienstes geschieht nach Mitteilung eines Ereignisses samt zugehöriger Daten (später werden diese Methodenparameter genannt) an das Objekt (Botschaft) y Ausführung eines Dienstes durch Auslösung neuer Ereignisse und evtl. Rücksendung einer Antwort Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-13 M. Philippsen / H. Stoyan Algorithmik 1, WS 2004/05, Folie 3-14 M. Philippsen 3.2 Objekte und Klassen in Java 3.2 Objekte und Klassen in Java (Objekt-)Klasse („object class, object type“) Variablen einfachen Typs Struktur- und verhaltensäquivalente Objekte werden gemäß Klassenkonstruktor erzeugt Die Objekte bilden dann die Ausprägungen bzw. Exemplare dieser Klasse („instance, class instance“) class Uhr { // Attribute ... // Methoden ... instance-of } y Mit Variablen einfachen Typs wird bei deren Vereinbarung zugleich ein Behälter für den Wert bereitgestellt (und in Java mit dem Default-Wert für diesen Typ initialisiert. Später: keine Initialisierung bei lokalen Variablen.) y Mit Angabe des Namens wird unmittelbar der Wert angesprochen (Wertsemantik) a 5 y Mit Objektvariablen wird nur ein Behälter für einen Zeiger auf ein Objekt des entsprechenden Typs angelegt (Referenzsemantik) y Der eigentliche Speicherplatz für die Objektinstanz muss dann noch angelegt werden und ist somit nicht fest angebunden Objekt nicht zugewiesen Algorithmik 1, WS 2004/05, Folie 3-15 a = 5; Referenzvariablen c Friedrich-Alexander-Universität Erlangen-Nürnberg Wert eingebracht z.B. durch int Objekt c Objekt zugewiesen Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Algorithmik 1, WS 2004/05, Folie 3-16 M. Philippsen 3.2 Objekte und Klassen in Java 3.2 Objekte und Klassen in Java Veranschaulichung Attribute („attribute, field“) Wertsemantik Als Attribute sind Variablen mit Werte- sowie Referenzsemantik erlaubt. Gemeinsam stellen sie den Zustand eines Objektes dar. Behälter Name Adresse a Zugriffsfunktion Wert Wertsemantik class Uhr { long minuten; long stunden; Referenzsemantik Name Behälter Adresse Adresse d. Objekta Zugriffsfunktion behälters Behälter Adresse TimeZone zeitzone; Objektwert } Über die Darstellung von Referenzen ist dem Programm nichts bekannt, mit Referenzen kann man nicht rechnen. Friedrich-Alexander-Universität Erlangen-Nürnberg Referenzsemantik Referenzvariable ist vom Typ TimeZone. Es können nur Verweise auf TimeZone-Objekte zugewiesen werden (später genauer). Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-17 M. Philippsen Algorithmik 1, WS 2004/05, Folie 3-18 M. Philippsen 3.2 Objekte und Klassen in Java 3.2 Objekte und Klassen in Java Konstruktoren („constructor“) Vorbesetzte Attribute und explizite Konstruktoren Ein Konstruktor erzeugt ein Objekt einer angegebenen Klasse (und belegt den hierfür nötigen Speicherplatz). Der Konstruktor einer Klasse trägt den Namen der Klasse. Falls kein Konstruktor angegeben ist, hat eine Java-Klasse den impliziten Konstruktor <Klassenname>(). Attribute werden bei Objekterzeugung mit dem angegebenen Wert vorbesetzt Ein Konstruktor wird mit Hilfe des Operators new aufgerufen. class Uhr { long minuten; long stunden; TimeZone zeitzone; } Erzeugt neue Instanz und liefert Referenz auf diese ... Uhr c = new Uhr(); ... Behälter für Referenzvariable Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-19 Impliziter Konstruktor M. Philippsen Wenn der implizite Konstruktor nicht ausreicht, können Konstruktoren explizit programmiert werden: Hier: ein expliziter Konstruktor mit Initialisierungscode und einem Eingabeparameter class Uhr { long minuten; long stunden; TimeZone zeitzone = new TimeZone("UTC"); final Date herstellungsdatum = new Date() ; Uhr (long min) { stunden = min/60; //Division ohne Rest (Ganzzahl) minuten = min%60; //Modulo-Operation } } //Nächste Vorl. mehr Operationen Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-20 M. Philippsen 3.2 Objekte und Klassen in Java 3.2 Objekte und Klassen in Java Reihenfolge der Konstruktorenaktivierung Zugriff auf die Attribute (bzw. Variablen) eines Objektes c Attribute werden bei Objekterzeugung mit dem angegebenen Wert vorbesetzt. c d Expliziter Konstruktor mit Initialisierungscode u. Eingabeparameter class Uhr { long minuten; long stunden; TimeZone zeitzone = new TimeZone("UTC"); final Date herstellungsdatum = new Date() ; Uhr(long min) { stunden = min / 60; minuten = min % 60; } ... Uhr(long min) { stunden = min / 60; minuten = min % 60; } ... y im Fall eines Zugriffs von Außen (nicht immer erlaubt): über c.<variablenname> } ... Uhr c = new Uhr(600); ... c.stunden = ... ... Uhr c = new Uhr(600); ... Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-21 y im Inneren des Objekts: über den Variablennamen Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Algorithmik 1, WS 2004/05, Folie 3-22 3.2 Objekte und Klassen in Java 3.2 Objekte und Klassen in Java Objektvariable als Referenzvariable (1) Objektvariable als Referenzvariable (2) Bei der Vereinbarung von Objektvariablen wird keine Instanz angelegt. Referenzvariablen ohne zugeordnetes Objekt besitzen die leere Referenz null, auf die geprüft werden kann. Referenzvariablen können bei ihrer Vereinbarung oder später initialisiert werden. Bei Zuweisung an Referenzvariablen wird der Verweis kopiert, nicht das Objekt, auf das verwiesen wird. Uhr c1 = new Uhr(0); Uhr c2 = new Uhr(0); Uhr c3 = c2; Algorithmik 1, WS 2004/05, Folie 3-23 c1 Uhr1 00:00 c2 Uhr2 00:00 c3 Uhr c = null; ... // Falls Objekt noch nicht erzeugt wurde, // jetzt Instanz anlegen if (c == null) { //Gleichheitstest (==). Nächste Vorlesg.: c = new Uhr(); //mehr zu Code für Fallunterscheidungen } //und andere Ablaufstrukturen Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen / H. Stoyan Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Algorithmik 1, WS 2004/05, Folie 3-24 M. Philippsen 3.2 Objekte und Klassen in Java 3.2 Objekte und Klassen in Java Objektvariable als Referenzvariable (3) Objektvariable als Referenzvariable (4) Vergleich der Referenzvariablen prüft die Identität und nicht die Bestandteile (nur die Referenzen). Referenzkonstanten fixieren den Verweis; das Objekt, auf das verwiesen wird, kann verändert werden (bei bleibender Identität). Uhr c1 = new Uhr(0); Uhr c2 = new Uhr(0); Uhr c3 = c2; // c1 == c2 liefert false // c1.minuten == c2.minuten // liefert true c1 Uhr1 00:00 c2 Uhr2 00:00 // c1 == c2 liefert false // c1.minuten == c2.minuten // liefert true c3 c3.minuten = c3.minuten + 10; // c2 == c3 liefert true // c2.minuten == c3.minuten // liefert true // c1.minuten == c2.minuten // liefert false c1 Uhr1 00:00 c2 Uhr2 00:00 c3 c3.minuten = c3.minuten + 10; c1 Uhr1 00:00 c2 Uhr2 00:10 c3 Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-25 Uhr c1 = new Uhr(0); Uhr c2 = new Uhr(0); final Uhr c3 = c2; // c2 == c3 liefert true // c2.minuten == c3.minuten // liefert true // c1.minuten == c2.minuten // liefert false c1 Uhr1 00:00 c2 Uhr2 00:10 c3 Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Algorithmik 1, WS 2004/05, Folie 3-26 M. Philippsen 3.2 Objekte und Klassen in Java 3.2 Objekte und Klassen in Java Exkurs: Destruktor („destructor“) Nicht in Java! Objektgraph mit unreferenzierten Objekten Spezielle Methode, die ein Objekt vernichtet, d.h. den belegten Speicherplatz freigibt. Fehleranfällig, wenn dieser von Hand im Programmcode aufgerufen werden muss. In Java: automatische Speicherbereinigung („garbage collection“): Entstehung unreferenzierter Objekte: Uhr c1 Uhr c3 = new Uhr(0); //Uhr-Objekt //wird erzeugt c3 = null; //Uhr-Objekt //nicht mehr //erreichbar Uhr c2 y Der Speicherbereinigung ist ein spezielles Objekt der Laufzeitumgebung (virtuellen Maschine), das die Objektgraphen im Speicher durchsucht. y Wird ein Objekt gefunden, das nicht mehr referenziert wird, wird dieses gelöscht und der von diesem belegte Speicher freigegeben. Unreferenzierte Objekte gestrichelt Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-27 Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen / H. Stoyan Algorithmik 1, WS 2004/05, Folie 3-28 M. Philippsen 3.2 Objekte und Klassen in Java 3.3 Klassenhierarchien Klassenattribute („class attribute“) (Einfach-)vererbung (= Übernahme der Eigenschaften der Oberklasse) Attribute, die der Klasse als Ganzes zugeordnet sind. In Java werden diese mit dem Modifikator static eingeleitet. class Uhr { static long zaehler = 0; long seriennummer; Uhr() { seriennummer = zaehler; zaehler++; } } Uhr c1 = new Uhr(); Uhr c2 = new Uhr(); // c1.seriennummer ist 0 // c2.seriennummer ist 1 Der Zähler ist nicht an ein einzelnes Objekt gebunden, sondern an die Klasse als Ganzes. Bei jedem Aufruf des Konstruktors wird der Zähler inkementiert. Der aktuelle Stand liefert die Seriennummer der Uhr. (Initialisierung mit 0 beim Laden der Klassendefinition in die JVM.) Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-29 Uhr darstellen() Generalisierung Spezialisierung DigitalUhr schriftgröße Algorithmik 1, WS 2004/05, Folie 3-30 3.3 Klassenhierarchien 3.3 Klassenhierarchien Oberklasse („super class“) Eine Oberklasse einer Klasse K ist eine aus K unmittelbar oder mittelbar generalisierte Klasse. Unterklasse („subclass“) Eine Unterklasse einer Klasse K ist ein aus K unmittelbar oder mittelbar spezialisierte Klasse. Vererbung („inheritance“) Übernahme aller Eigenschaften (= Attribute und Operationen) der Oberklasse A durch die Unterklasse B: Vererbung zwischen Klassen y Neue Eigenschaften von B werden in B selbst festgelegt. y Abgeleitete Eigenschaften der Unterklasse B werden von der Oberklasse A übernommen (Verhaltensgleichheit). y Überschriebene Eigenschaften können nur Methoden sein. Sie entstehen wenn in der Unterklasse B eine Methode mit genau der selben Signatur wie in der Oberklasse A definiert wird (und eine neue Implementierung bereit gestellt wird) (Spezialisierung im engeren Sinn). Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-31 zifferblattfarbe 13:47 Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen AnalogUhr Zur Erinnerung: Uhr ist abstrakte Klasse: UhrObjekte existieren nicht. M. Philippsen Einfachvererbung wird zwischen Klassen unterstützt, wobei extends die Oberklasse angibt: class AnalogUhr extends Uhr { ... } Die Java-Klassenbibliothek definiert die Klasse Object, die Oberklasse aller Klassen ist. Vererbung wird in Java durch Ableitung von Eigenschaften realisiert: y Die Unterklasse übernimmt automatisch die Attribute sowie die Methodensignaturen und deren Implementierungen von der Oberklasse. y Später: Bei Spezialisierung durch Überschreiben einer Eigenschaft wird die Methode in der Unterklasse erneut vereinbart und implementiert. Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen / H. Stoyan Algorithmik 1, WS 2004/05, Folie 3-32 M. Philippsen 3.3 Klassenhierarchien 3.3 Klassenhierarchien Klassenhierarchie am Beispiel (1) Klassenhierarchie am Beispiel (2) (siehe Folie 3.22) Implementierung der Klasse Uhr Abgeleitete Klasse AnalogUhr class AnalogUhr extends Uhr { Color zifferblattfarbe; AnalogUhr(long min) { super(min); } ... } abstract class Uhr { static long zaehler = 0; long seriennummer; long minuten; long stunden; TimeZone zeitzone = new TimeZone("UTC"); final Date herstellungsdatum = new Date(); Abgeleitete Klasse DigitalUhr Uhr() { seriennummer = zaehler; zaehler++; } ... Obwohl Uhr eine abstrakte Klasse ist, werden dennoch Variablen und ein Konstruktor angegeben, der für alle Unterklassen gemeinsam sinnvoll ist. Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen 3.3 Klassenhierarchien Uhr(…) Algorithmik 1, WS 2004/05, Folie 3-34 M. Philippsen / H. Stoyan 3.3 Klassenhierarchien Mehrfachvererbung (= Übernahme der Eigenschaften von mehr als einer Oberklasse) Uhr anzeigen() DigitalUhr zifferblattfarbe AnalogDigitalUhr anzeigenanordnung 13:47 Verdecken von Variablen Die in der Unterklasse deklarierten Attribute ergänzen die Attribute der Oberklasse; sie kommen zusätzlich hinzu. class Ober { int a1; float f1; } AnalogUhr schriftgröße In Java gibt es keine Sprachelemente, um Mehrfachvererbung direkt auszudrücken! class Unter extends Ober { boolean a1; //zusätzliches Attribut float f2; //zusätzliches Attribut } Eine Unterklasse kann aber auch ein Attribut gleichen Namens aber anderen Typs deklarieren. In der Unterklasse verdeckt dieses Attribut dann das Attribut aus der Oberklasse. Zugriff ist aber über „super.“ möglich: class Unter extends Ober { ... a1 = ... //spricht Wahrheitswert an super.a1 = ..//spricht int-Wert an ... } Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-35 Der Konstruktor ruft einen Konstruktor der Oberklasse auf, um die gemeinsamen Attribute zu initialisieren. Spezielle Notation für solche Aufrufe: super(…) statt Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-33 13:47 class DigitalUhr extends Uhr { int schriftgroesse; DigitalUhr(long min) { super(min); } ... } Beide Unterklassen deklarieren eigene zusätzliche Attribute. Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Algorithmik 1, WS 2004/05, Folie 3-36 M. Philippsen 3.4 Umsetzung von UML-Klassendiagrammen in Java 3.4 Umsetzung von UML-Klassendiagrammen in Java Umsetzung UML in Java Assoziationen zwischen Klassen der Bibliothek class Klasse { // Attribute Typ1 Attr1 = Anfangswert1; Typ2 Attr2; // Konstruktoren Klasse () { } // Methoden, später mehr dazu void Operation1() { } void Operation2(Typ1 Parameter1, Typ2 Parameter2) { } Ergebnistyp1 Operation3() { } } Klasse Attr1 : Typ1 = Anfangswert1 Attr2 : Typ2 Klasse() Operation1() Operation2(Parameter1:Typ1, Parameter2:Typ2) Operation3 : Ergebnistyp1 Friedrich-Alexander-Universität Erlangen-Nürnberg Assoziationsname Exemplar Leserichtung ist Exemplar von Buch ist vorhanden als Assoziationsname in umgekehrter Leserichtung entleiht gibt zurück Bibliotheksmitglied Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-37 M. Philippsen Algorithmik 1, WS 2004/05, Folie 3-38 M. Philippsen 3.4 Umsetzung von UML-Klassendiagrammen in Java 3.4 Umsetzung von UML-Klassendiagrammen in Java Assoziationen zwischen Klassen der Bibliothek Weiterer Eigenschaften von Assoziationen Exemplar entleiht class Exemplar { ... } class Bibliotheksmitglied { Exemplar entliehenesExemplar;//unzureichend // Exemplar zurückgegebenesExemplar; } gibt zurück Referenz ist Zeiger auf Exemplar, gemäß Leserichtung der Assoziation. Bibliotheksmitglied Beachte Kardinalitäten: Ein Bibliotheksmitglied kann mehrere Exemplare ausleihen. Eine Referenz zeigt aber nur auf ein Exemplar. Beachte: Bei dieser Modellierung gibt es keine Referenz vom Exemplar auf das ausleihende Bibliotheksmitglied. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-39 berichtet an {Vorgesetzter.Gehalt > Untergebener.Gehalt} Untergebener Mitarbeiter Vorgesetzter class Mitarbeiter { Mitarbeiter Vorgesetzer; Mitarbeiter Untergebene; //unzureichend } Beachte: Restriktionen können nicht in der Datenstruktur repräsentiert werden, sondern müssen auf andere Weise sichergestellt werden (Methoden, Fehlermeldungen, …) Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Algorithmik 1, WS 2004/05, Folie 3-40 M. Philippsen 3.4 Umsetzung von UML-Klassendiagrammen in Java 3.4 Umsetzung von UML-Klassendiagrammen in Java Restriktionen: Assoziationsklasse („association class“) Exemplar ist entweder Buch oder Zeitschrift Exemplar 1..* ist Exemplar von 1 1..* is {xor} t Ex emp lar v on Exemplar Buch 1..*ist Exemplar von Zeitschrift class Exemplar { Buch buchInformationen; Date kaufdatum; } class Exemplar { Buch buchInformationen; Zeitschrift zeitschriftInformationen; } Bei 1:n-Beziehungen können die Attribute der Assoziationsklasse Auf die „Seite der n“ gezogen werden. Beachte: Restriktionen können nicht in der Datenstruktur repräsentiert werden, sondern müssen auf andere Weise sichergestellt werden (Methoden, Fehlermeldungen, …) Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen 3.4 Umsetzung von UML-Klassendiagrammen in Java Buch 1 0..1 entleiht Ein Mitglied darf von einem Buch nur 1 Exemplar ausleihen! Bibliotheksmitglied class Leihe { Zeit dauer; Exemplar ex; Bibliotheksmitglied person; Buch buchInformationen; //unzureichend } Modellierte Regel lässt sich nicht unmittelbar mit Klassen und Referenzen alleine darstellen. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-43 Algorithmik 1, WS 2004/05, Folie 3-42 M. Philippsen 3.4 Umsetzung von UML-Klassendiagrammen in Java Mehrstellige Assoziationen („n-ary association“) setzen Objekte von mehr als zwei Klassen zueinander in Beziehung. Dauer: Zeit Bei n:m-Beziehungen muss eine neue Klasse für die Assoziation eingeführt werden. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-41 0..1 Buch Kaufdatum 1 Exemplar 1 Abschnitt * * Text Kapitel Autor Anzahl Seiten * 1 Buch Titel Verlag Eine Aggregation („aggregation“) ist eine spezielle Form einer Assoziation, die eine ist-Teil-von-Beziehung zwischen einem Ganzen und dessen Bestandteilen ausgedrückt. Sie wird durch eine leere Raute beim Ganzen am Ende der Assoziation dargestellt. Æ Referenz auf die enthaltende(n) Komponente(n), ggf. null Referenz auf die enthaltene(n) Komponente(n), ggf. null Eine Komposition („composition, composite aggregation“) ist eine Aggregation, bei der ein Bestandteil genau zu einem Ganzen gehört und nicht ohne das Ganze existieren kann. Dargestellt wird die Komposition durch eine gefüllte Raute. Æ Referenz auf die enthaltende(n) Komponente(n), nicht null nicht in Datenstruktur festschreibbar. Referenz auf die enthaltene(n) Komponente(n), ggf. null Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Algorithmik 1, WS 2004/05, Folie 3-44 M. Philippsen 3.5 Andere zusammengesetzte Datentypen 3.5 Andere zusammengesetzte Datentypen Alle Programmiersprachen bieten neben primitiven Typen auch zusammengesetzte Typen an. Zeichenfolgen y Zeichenfolgen („dies ist eine Zeichenfolge“) y Verbunde y Reihungen Einzelzeichen des Unicodes werden in Java durch einzelnen Anführungszeichen abgegrenzt: y char Einzelzeichen = 'x'; In Java sind alle zusammengesetzten Typen einheitlich durch Klassen realisiert. Für Zeichenfolgen und Reihungen gibt es in Java (und in den meisten Programmiersprachen) eine besondere Notation, die sich prinzipiell auf die Klassen-Notation zurückführen lässt. Zeichenfolgen werden durch (doppelte) Gänsefüßchen abgegrenzt: y "" y "hello" //leere Zeichenfolge //normale Zeichenfolge Es gibt spezielle Operatoren für diesen zusammengesetzten Datentyp: y Konkatenation: "hello "+"students" y Zeichenfolgenvergl. "hello "+"students" == "hello students" Zeichenfolgen sind Objekte der bereits im Sprachumfang vereinbarten Klasse String (genauer: java.lang.String) Friedrich-Alexander-Universität Erlangen-Nürnberg Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-45 M. Philippsen Algorithmik 1, WS 2004/05, Folie 3-46 M. Philippsen 3.5 Andere zusammengesetzte Datentypen 3.5 Andere zusammengesetzte Datentypen Spezialzeichen Reihung („array“) = geordnete Menge typgleicher Variablen. Für manche Zeichen des Unicodes gibt es besondere Schreibweisen. Vereinbarung: <Typ> [] <Name> Spezialzeichen Unicode Ersatzdarstellung Rückschritt („backspace") horizontaler Tabulator („TAB“) neue Zeile („line feed") Seitenvorschub („form feed“) Wagenrücklauf („carriage return“) doppeltes Anführungszeichen einfaches Anführungszeichen Rückstrich („backslash“) \u0008 \u0009 \u000a \u000c \u000d \u0022 \u0027 \u005c \b \t \n \f \r \" \‘ \\ Siehe ASCII-Tabelle, Abschnitt 1.1 Die Größe (= Anzahl der Elemente) wird bei Erzeugung des Arrays festgelegt, kann dann aber nicht mehr geändert werden. Die Erzeugung kann bei oder nach der Variablendeklaration stattfinden. y Beispiel für die Erzeugung eines int-Arrays der Größe 10: int[] ai; //ai ist noch null-Referenz ai = new int[10]; //ai ist initialisiert oder: Escape-Zeichen Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-47 y Beispiele: int[] ai; int[] ai = new int[10]; Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Algorithmik 1, WS 2004/05, Folie 3-48 M. Philippsen 3.5 Andere zusammengesetzte Datentypen 3.5 Andere zusammengesetzte Datentypen Reihungen sind Objekte einer bereits im Sprachumfang vereinbarten (anonymen) Klasse. Im Unterschied zu Objekten, die der Programmierer anlegt, gibt es zusätzliche sprachliche Möglichkeiten für Zugriffe auf die Variablen von Reihungsobjekten. Beispiel y Im Attribut length eines Reihungsobjekts kann die Größe der erzeugten Reihung abgelesen werden. y Beispiel: ai.length == 10 // liefert (nach der // Erzeugung von oben) true Das erste Array-Element hat den Index 0! Uhr[] uhren_liste = new Uhr[5]; uhren_liste[0] = new AnalogUhr(); uhren_liste[1] = new DigitalUhr(); // 5 Uhren int l = uhren_liste.length; // l ist 5 Nach der Erzeugung gibt es Zugriffsfunktionen („Namen“) für jedes Element der Reihung: ai[0], ai[1], ... , ai[ai.length-1] y Beispiel Zugriffe: ai[1] = ai[3 + 1]; // Schreibt 2. Array-Element (Nr.1) // und liest 5. Array Element (Nr.4) Friedrich-Alexander-Universität Erlangen-Nürnberg Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-49 M. Philippsen Algorithmik 1, WS 2004/05, Folie 3-50 M. Philippsen 3.5 Andere Zusammengesetzte Datentypen 3.5 Andere Zusammengesetzte Datentypen Mehrdimensionale Reihungen: Mehrdimensionale Reihungen Der Typ eines Arrays kann beliebig sein (Klasse, primitiver Typ oder wiederum ein Array-Typ). Daher sind mehr-dimensionale Arrays möglich: gibt es in den meisten Programmiersprachen. Aber meistens nicht als Reihungen von Reihungen, sondern als „rechteckige“ mehrdimensionale Datenfelder. int[][] aai; Exemplar[] geliehen; // Array aus int-Arrays // Array aus Objektreferenzen Auch im mehrdimensionalen Fall müssen die Arrays jeweils einzeln erzeugt werden: aai = new int[2][]; // // aai[0] = new int[1]; // // aai[1] = new int[2]; // // Erzeuge Array zur Speicherung von 2 int-Arrays Erzeuge erstes intArray der Länge 1 Erzeuge zweites Array der Länge 2 Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-51 y Mehrdimensionales Datenfeld (C, C++, Fortran, ...) … Bei linearer Abbildung in den HauptSpeicher kann aus dem Index (i,j) und dem Platzbedarf des Grundtyps die Speicheradresse ermittelt werden. y Reihung von Reihung (Java) Nicht-“rechteckige“ mehrdimensionale Reihungen sind möglich (fehlende Zeilen, doppelt genutzte Zeilen, unterschiedlich lange Zeilen) Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Algorithmik 1, WS 2004/05, Folie 3-52 M. Philippsen 3.5 Andere zusammengesetzte Datentypen Mehr über Reihungen: Bei der Erzeugung dürfen die Array-Größen aus Ausdrücken berechnet werden: int a = b = 10; Exemplar[] geliehen = new Exemplar[a + b]; Es sind auch direkte Array-Initialisierungen möglich: int[] quadrat = {1, 4, 9, 16, 25, 36, 49}; int[][] aai = { { 1, 2 }, { 3, 4 } }; Bei nicht initialisierten Arrays werden die Elemente implizit auf Standardwerte gesetzt: y 0 bei int, short, byte, float, double y false bei boolean y null bei Referenzen Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-53 M. Philippsen