Algorithmik 1 Prof. Dr. Michael Philippsen / Prof. Dr. Herbert Stoyan Friedrich-Alexander-Universität Erlangen-Nürnberg Informatik 2/8 Programmiersysteme / Künstliche Intelligenz Kapitel 3 - Datenstrukturen im objektorientierten Programmieren 3.1 3.2 3.3 3.4 3.5 Variablen einfachen Typs Objekte und Klassen in Java Klassenhierarchien Umsetzung von UML-Klassendiagrammen Andere zusammengesetzte Datentypen Handy aus! Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-2 M. Philippsen 1.5 Programmgesteuerter Rechner (Babbage, 1833) Speicher EingabeDaten, 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 M. Philippsen / H. Stoyan 1.6 Von-Neumann-Rechner Sedezimale Darstellung „Hex-Dump“ Speicher, konzeptuell Adresse 0 Adresse 4 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 Algorithmik 1, WS 2004/05, Folie 3-4 M. Philippsen 3.1 Variablen einfachen Typs Eigenschaften einer Speicherzelle: 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 M. Philippsen 3.1 Variablen einfachen Typs Ablauf des Zugriffs über den Namen: 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 Algorithmik 1, WS 2004/05, Folie 3-6 M. Philippsen 3.1 Variablen einfachen Typs Ein Name ist eine beliebig lange Folge von „Java-Buchstaben“ und „Java-Ziffern“, beginnend mit einem „Java-Buchstaben“, wobei: 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. Ein Name darf also nicht mit einer Ziffer beginnen. Beispiele: y gültige Bezeichner: y ungültige Bezeichner: i3, algo_1, MAX_WERT 1algo, 12HUNDERT, 0nixgut Wichtig: Groß- und Kleinschreibung wird unterschieden. Algo1 und algo1 sind also zwei ganz verschiedene Bezeichner. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-7 M. Philippsen 3.1 Variablen einfachen Typs Jede Variable oder Konstante besitzt einen Typ. y Festlegung des gültigen Wertebereichs y Festlegung der anwendbaren Grundoperationen (später mehr) Einfache Typen: Primitiver Typ Numerischer Typ Ganzzahliger Typ byte char long int Gleitkomma-Typ short float double boolean Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-8 M. Philippsen 3.1 Variablen einfachen Typs Basistyp Beschreibung boolean Wahrheitswert Wertebereiche true, false 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 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 char Einzelzeichen Unicode, 16 Bits, http://www.unicode.org Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-9 M. Philippsen 3.1 Variablen einfachen Typs restlicher Text muss exakt wie angegeben im Programm erscheinen. <XXX> ist ein Platzhalter; im Programm zu ersetzen. Art Syntaktische Form Beispiele unbenannte Konstante (Literal) <Wert> 1, true, 'c' Variablenvereinbarung (Deklaration) <Typ> <Name>; int a; lesender Zugriff <Name> a + 1 schreibender Zugriff (Zuweisung) <Name> = <Wert>; a = 1; <Wert> kann auch ein zu berechnender Ausdruck sein. Initialwert der Variable ist typspezifisch. Meist 0. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-10 M. Philippsen 3.1 Variablen einfachen Typs Art Syntaktische Form Beispiele Variablenvereinbarung mit Vorbesetzung (Deklaration mit Initialisierung) <Typ> <Name> = <Wert>; int a = 1; Vereinbarung einer benannten Konstanten mit Einmaldefinition final <Typ> <Name> = <Wert>; final float pi = 3.14159; Der Übersetzer stellt sicher, dass es nur eine Definition im Programm gibt. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-11 M. Philippsen / H. Stoyan 3.1 Variablen einfachen Typs Wert von a nach der Anweisung Beispiele int a = 1; //Deklaration //Initialisierung mit //Literal 1 1 a = a + 1; //Inkrementierung 2 a++; //Inkrementierung 3 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 später: d bleibt als lokale Variable uninitialisiert. Friedrich-Alexander-Universität Erlangen-Nürnberg 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“) Funktionalität Struktur Gegenstand der Anschauung Operatorsignaturen Dienst Algorithmen und Datenstrukturen Klasse („class“) Objektklasse als KomponentenBaumuster Attribute Assoziationen Operatorimplementierungen Funktionalität Struktur Menge gleichartiger Gegenstände der Anschauung Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-13 M. Philippsen / H. Stoyan 3.2 Objekte und Klassen in Java 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“) 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-14 M. Philippsen 3.2 Objekte und Klassen in Java (Objekt-)Klasse („object class, object type“) 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 } Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-15 M. Philippsen 3.2 Objekte und Klassen in Java Variablen einfachen Typs 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 Wert eingebracht z.B. durch int a = 5; Referenzvariablen 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 c Objekt nicht zugewiesen Objekt c Objekt zugewiesen Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-16 M. Philippsen 3.2 Objekte und Klassen in Java Veranschaulichung Wertsemantik Name Behälter Adresse a Zugriffsfunktion Wert Referenzsemantik Name Behälter Adresse Adresse d. Objekta Zugriffsfunktion behälters Behälter Adresse Objektwert Über die Darstellung von Referenzen ist dem Programm nichts bekannt, mit Referenzen kann man nicht rechnen. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-17 M. Philippsen 3.2 Objekte und Klassen in Java Attribute („attribute, field“) Als Attribute sind Variablen mit Werte- sowie Referenzsemantik erlaubt. Gemeinsam stellen sie den Zustand eines Objektes dar. Wertsemantik class Uhr { long minuten; long stunden; TimeZone zeitzone; } 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-18 M. Philippsen 3.2 Objekte und Klassen in Java Konstruktoren („constructor“) 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>(). 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 3.2 Objekte und Klassen in Java Vorbesetzte Attribute und explizite Konstruktoren Attribute werden bei Objekterzeugung mit dem angegebenen Wert vorbesetzt 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 Reihenfolge der Konstruktorenaktivierung 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 c = new Uhr(600); ... Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-21 M. Philippsen 3.2 Objekte und Klassen in Java Zugriff auf die Attribute (bzw. Variablen) eines Objektes c y im Inneren des Objekts: über den Variablennamen ... 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 = ... Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-22 M. Philippsen / H. Stoyan 3.2 Objekte und Klassen in Java Objektvariable als Referenzvariable (1) 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. 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 Algorithmik 1, WS 2004/05, Folie 3-23 M. Philippsen 3.2 Objekte und Klassen in Java Objektvariable als Referenzvariable (2) 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; c1 Uhr1 00:00 c2 Uhr2 00:00 c3 Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-24 M. Philippsen 3.2 Objekte und Klassen in Java Objektvariable als Referenzvariable (3) Vergleich der Referenzvariablen prüft die Identität und nicht die Bestandteile (nur die Referenzen). 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 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:10 c3 Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-25 M. Philippsen 3.2 Objekte und Klassen in Java Objektvariable als Referenzvariable (4) 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); final Uhr c3 = c2; // c1 == c2 liefert false // c1.minuten == c2.minuten // liefert true c1 Uhr1 00:00 c2 Uhr2 00:00 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:10 c3 Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-26 M. Philippsen 3.2 Objekte und Klassen in Java Exkurs: Destruktor („destructor“) Nicht in Java! 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“): 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. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-27 M. Philippsen / H. Stoyan 3.2 Objekte und Klassen in Java Objektgraph mit unreferenzierten Objekten Entstehung unreferenzierter Objekte: Uhr c1 Uhr c3 = new Uhr(0); //Uhr-Objekt //wird erzeugt c3 = null; //Uhr-Objekt //nicht mehr //erreichbar Uhr c2 Unreferenzierte Objekte gestrichelt Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-28 M. Philippsen 3.2 Objekte und Klassen in Java Klassenattribute („class attribute“) 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 M. Philippsen 3.3 Klassenhierarchien (Einfach-)vererbung (= Übernahme der Eigenschaften der Oberklasse) Uhr darstellen() Generalisierung Spezialisierung DigitalUhr schriftgröße AnalogUhr zifferblattfarbe 13:47 Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-30 Zur Erinnerung: Uhr ist abstrakte Klasse: UhrObjekte existieren nicht. M. Philippsen 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: 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 M. Philippsen / H. Stoyan 3.3 Klassenhierarchien Vererbung zwischen Klassen 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 Algorithmik 1, WS 2004/05, Folie 3-32 M. Philippsen 3.3 Klassenhierarchien Klassenhierarchie am Beispiel (1) Implementierung der Klasse Uhr abstract class Uhr { static long zaehler = 0; long seriennummer; long minuten; long stunden; TimeZone zeitzone = new TimeZone("UTC"); final Date herstellungsdatum = new Date(); 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 Algorithmik 1, WS 2004/05, Folie 3-33 M. Philippsen 3.3 Klassenhierarchien Klassenhierarchie am Beispiel (2) (siehe Folie 3.22) Abgeleitete Klasse AnalogUhr class AnalogUhr extends Uhr { Color zifferblattfarbe; AnalogUhr(long min) { super(min); } ... } Abgeleitete Klasse DigitalUhr class DigitalUhr extends Uhr { int schriftgroesse; DigitalUhr(long min) { super(min); } ... } Beide Unterklassen deklarieren eigene zusätzliche Attribute. Der Konstruktor ruft einen Konstruktor der Oberklasse auf, um die gemeinsamen Attribute zu initialisieren. Spezielle Notation für solche Aufrufe: super(…) statt Uhr(…) Friedrich-Alexander-Universität Erlangen-Nürnberg 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 13:47 AnalogUhr schriftgröße zifferblattfarbe AnalogDigitalUhr anzeigenanordnung 13:47 In Java gibt es keine Sprachelemente, um Mehrfachvererbung direkt auszudrücken! Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-35 M. Philippsen 3.3 Klassenhierarchien 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; } 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-36 M. Philippsen 3.4 Umsetzung von UML-Klassendiagrammen in Java Umsetzung UML in Java Klasse Attr1 : Typ1 = Anfangswert1 Attr2 : Typ2 Klasse() Operation1() Operation2(Parameter1:Typ1, Parameter2:Typ2) Operation3 : Ergebnistyp1 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() { } } Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-37 M. Philippsen 3.4 Umsetzung von UML-Klassendiagrammen in Java Assoziationen zwischen Klassen der Bibliothek 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-38 M. Philippsen 3.4 Umsetzung von UML-Klassendiagrammen in Java Assoziationen zwischen Klassen der Bibliothek 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 M. Philippsen 3.4 Umsetzung von UML-Klassendiagrammen in Java Weiterer Eigenschaften von Assoziationen 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 Algorithmik 1, WS 2004/05, Folie 3-40 M. Philippsen 3.4 Umsetzung von UML-Klassendiagrammen in Java Restriktionen: Exemplar ist entweder Buch oder Zeitschrift Exemplar 1..* ist Exemplar von 1 1..* is {xor} t Ex emp lar v on 1 Buch Zeitschrift class Exemplar { Buch buchInformationen; Zeitschrift zeitschriftInformationen; } 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 Algorithmik 1, WS 2004/05, Folie 3-41 M. Philippsen 3.4 Umsetzung von UML-Klassendiagrammen in Java Assoziationsklasse („association class“) Exemplar 1..*ist Exemplar von 1 Buch Kaufdatum class Exemplar { Buch buchInformationen; Date kaufdatum; } Bei 1:n-Beziehungen können die Attribute der Assoziationsklasse Auf die „Seite der n“ gezogen werden. 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-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. Buch 1 Exemplar 0..1 0..1 entleiht Ein Mitglied darf von einem Buch nur 1 Exemplar ausleihen! Dauer: Zeit 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 M. Philippsen 3.4 Umsetzung von UML-Klassendiagrammen in Java 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 Algorithmik 1, WS 2004/05, Folie 3-44 M. Philippsen 3.5 Andere zusammengesetzte Datentypen Alle Programmiersprachen bieten neben primitiven Typen auch zusammengesetzte Typen an. y Zeichenfolgen („dies ist eine Zeichenfolge“) y Verbunde y Reihungen 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. Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-45 M. Philippsen 3.5 Andere zusammengesetzte Datentypen Zeichenfolgen Einzelzeichen des Unicodes werden in Java durch einzelnen Anführungszeichen abgegrenzt: y char Einzelzeichen = 'x'; 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 Algorithmik 1, WS 2004/05, Folie 3-46 M. Philippsen 3.5 Andere zusammengesetzte Datentypen Spezialzeichen Für manche Zeichen des Unicodes gibt es besondere Schreibweisen. 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 Escape-Zeichen Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-47 M. Philippsen 3.5 Andere zusammengesetzte Datentypen Reihung („array“) = geordnete Menge typgleicher Variablen. Vereinbarung: <Typ> [] <Name> y Beispiele: int[] ai; 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: int[] ai = new int[10]; Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-48 M. Philippsen 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. 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 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 Algorithmik 1, WS 2004/05, Folie 3-49 M. Philippsen 3.5 Andere zusammengesetzte Datentypen Beispiel 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 Friedrich-Alexander-Universität Erlangen-Nürnberg Algorithmik 1, WS 2004/05, Folie 3-50 M. Philippsen 3.5 Andere Zusammengesetzte Datentypen Mehrdimensionale Reihungen: Der Typ eines Arrays kann beliebig sein (Klasse, primitiver Typ oder wiederum ein Array-Typ). Daher sind mehr-dimensionale Arrays möglich: 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 M. Philippsen 3.5 Andere Zusammengesetzte Datentypen Mehrdimensionale Reihungen gibt es in den meisten Programmiersprachen. Aber meistens nicht als Reihungen von Reihungen, sondern als „rechteckige“ mehrdimensionale Datenfelder. 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 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