Objektorientierte Datenbanken Ralf Möller, FH-Wedel Beim vorigen Mal: Umsetzung in objektorientierte Modellierung auf Implementierungsebene am Beispiel Java Klassen und Instanzen Heute: Fortsetzung: Generalisierung, Relationen Lernziele: Java aus UML-Sicht verstehen Kurzeinführung in OOP am Beispiel Java In Übungen noch vertieft Vordefinierte Klassen Beispiele: java.lang.String (Notation (“OODB.") java.util.Vector java.util.Dictionary Entsprechende Operationen zum Erzeugen und zum Zugriff auf Elemente bzw. zum Ersetzen von Elementen definiert Vordefinierte Verknüpfungsoperationen java.util.Vector Vector x = new Vector; x.setElementAt(Integer(42), 0); x.setElementAt(Integer(43), 1); x.elementAt(0); x.length(); Vector y = new Vector(27); x.addElement(56); Klassen als Attributtypen public class Polyeder { java.util.Vector hülle; ... } public class Flaeche { ... } public class Kante { Punkt p1; Punkt p2; ... } public class Punkt { ... } Polyeder +PolyID : int +... +Gewicht() : float +Volumen() : float +skalieren() +verschieben() +rotieren() Flächen +FlächenID : int Hülle +... 1 1..* 1 4..* +Umfang() : float +Volumen() : float Punkte +X : float Kanten +Y : float Begrenzung StartEnde +KantenID : int +Z : float +... 2* 3..* 3..* 2* * * +rotieren() +Länge() : float +verschieben() +skalieren() Arrays am Beispiel int a[] = new int[100]; a[0] = 1; for (int i = 1; i < b.length; i++) { a[i] = a[i-1] } Arrays vs. Vektoren Bei Array muß die Maximallänge zur Erzeugungszeit (nicht Übersetzungszeit) bekannt sein Bei Vektoren (Instanzen der Klasse Vector) ist die Länge variabel Länge kann bei beiden erfragt werden (length) Programme In Java ist eine Klasse auch ein Programm, wenn eine sog. Main-Methode definiert ist Class Test { ... public static void main (String argv[]) { ... } } Generalisierung / Spezialisierung Generalisierungen/Spezialisierungen modellieren Beziehungen zwischen Klassen (d.h. Mengen von Instanzen) In Java Umsetzung durch extends-Konstrukt Umsetzung in Java bietet nur Spezialisierung Vererbung in Java unterstützt (Einfachvererbung) Attribute können nur von ein einer Oberklasse geerbt werden, Angabe beliebig vieler Interfaces möglich Namenskollisionen definieren Einschränkungen Betrachtung von Overlapping und Disjoint machen also nur für Interfaces Sinn (wird aber immer mit Klasse kombiniert, ist also in Java ohne Bedeutung) Unterscheidung von Generalisierungsarten (mit Namen) auch in Java höchstens für Interfaces sinnvoll (aber nicht unterstützt) Abstrakte Klassen können in Java markiert werden Keine Instantiierbarkeit Spezialisierung, Subtypen, Substitutionsprinzip In Java nur Spezialisierung, da Quellcode nicht neu übersetzt werden soll Eine Klasse, die eine andere Klasse erweitert, definiert einen Subtypen (dito für Interface) Annahme: Im Code steht Methodenaufruf Objektausdruck . Methodenname ([Ausdruck {, Ausdruck}]) Zulässig nur wenn Objektausdruck ein Objekt liefert, das Instanz eines Subtyps von einer Klasse ist, die eine Methode entsprechenden Typs bereitstellt. Spezialisierung und Vererbung Attribute Vererbung „nach unten“ Sichtbarkeit steuerbar (public, protected, private) Operationen Vererbung „nach unten“ Überschreiben einer Methode gleichen Typs in Unterklasse Aufruf der überschriebenen Methode m durch super[.m](...) Dynamisches Binden Methode in der speziellsten Oberklasse (zuerst) anwenden Kontravarianzprinzip bei Behandlung der MethodenParametertypen durch den Compiler Beispiel: Einsatz von Objekten in Rahmenwerken (Frameworks) Spezielles Framework: Java-Laufzeitumgebung Annahme: Objekt soll auf Terminal gedruckt werden Notwendig: Objektbeschreibung als Zeichenkette Nachricht: toString() Option: Spezielle Methoden in „eigenen“ Klassen programmieren Interfaces und Typen Beschreibung einer Menge von Nachrichten, die an ein Objekt gesandt werden können, das das Interface implementiert Keine Beschreibung der Struktur der Objekte Interface-Spezifikationen definieren Typen Least Commitment Prinzip Deklaration von Variablen- und Attributtypen durch Verwendung von Interfaces Auswahl der konkreten Struktur nach pragmatischen Gesichtspunkten zur Erzeugungszeit der Variablen- bzw. Attributwerte durch Instantiierung von Klassen Beispiel public interface ... { ... } public class ... extends ... implements ... , ... { ... } Relationen in UML: Graphische Notation Komposition +Hörer +Nachfolger 1..* hören * 1 +Prüfling * Prüfungen +Note : Decimal +Datum : Date +verschieben() Assistenten +Fachgebiet : String +Gehalt() : short Vorlesungen +VorlNr : int +Titel : String +SWS : int +AnzHörer() : int +DurchfallQuote() : float * 1 * 1 +Boss * arbeitenFür Angestellte +PersNr : int +Name : String +Gehalt() : short 1 voraussetzen * * * +Prüfungsstoff gelesenVon Studenten +MatrNr : int +Name : String +Semester : int +Notenschnitt() : float +SummeWochenstunden() : short +Prüfer Professoren +Rang : String +Notenschnitt() : float +Gehalt() : short +Lehrstundenzahl() : short 1 +Dozent Beispiel: Uni-Schema Relationen Assoziationen, Aggregationen und Komposition modellieren auf Klassenebene Beziehungen zwischen Instanzen (der beteiligten Klassen, z.B. K1 und K2) Umsetzung durch Einführung neuer Attribute für K1 und K2, Verwendung von „globalen“ Verzeichnissen (Dictionaries) Umsetzung durch Klassenfelder (Attribute) Geht bei funktionaler Einschränkung Verwendung des Rollennamens als Attributname, sonst Attributname aus Relationenname generieren Gültigkeitsbereich durch Typangaben ausdrückbar Umsetzung durch Klassenfelder mit Vectortyp Notwendig bei nicht vorhandener funktionaler Einschränkung Wechselseitige Referenzierung Notwendig bei fehlender Navigierbarkeitsangabe Multiplizitätsüberwachung durch manuell zu erstellenden Code Zugriff auf Elemente einer Relation nur über Objekte Probleme mit nebenläufigen Kontrollflüssen und temporär nicht vollständig etablierten wechselseitigen Referenzierungen Relationen: detailliertere Beschreibung Multiplizität gibt an, wieviel Objekte an der Relation beteiligt sind Navigierbarkeit beschränkt den bidirektionalen Charakter von Relationen Constraints beschränken den Gültigkeitsbereich von Relationen Rollennamen beschreiben die Endpunkte der Relation Umsetzung durch Verzeichnisse (Dictionaries) Abstrakte Klassen zur Implementierung von Assoziationen Instantiierbare Unterklasse: Hashtables Dictionaries Assoziation von „Elementen“ mit „Schlüsseln“ var Dictoriary d; d=new Hashtable; d.put(534958345, „Meyer“) d.get(534958345) d.remove(534958345) Aggregation, Komposition In Java keine besonderen Sprachkonstrukte Polyeder +PolyID : int +... +Gewicht() : float +Volumen() : float +skalieren() +verschieben() +rotieren() Flächen +FlächenID : int Hülle +... 1..* 11 4..* +Umfang() : float +Volumen() : float Punkte +X : float Kanten +Y : float Begrenzung StartEnde +KantenID : int +Z : float +... 2* 3..* 3..* 2* * * +rotieren() +Länge() : float +verschieben() +skalieren() Assoziationen: Constraints in Java Überwachung durch manuell zu erstellen Code Mehrstellige Relationen Umsetzung durch Einführung einer neuen Klasse mit entsprechenden Attributen, um auf die anderen an der Relation beteiligten Instanzen zu verweisen Lineare Traversierung von Datenstrukturen Iterator Objekt, das Traversierungszustand speichert Next-Operation zur Fortschreibung der Traversierung Operation zur Feststellung, ob Ende erreicht Beispiel: import java.util.*; var Dictoriary d; Iterator iter = d.iterator(); While (iter.hasNext()) { Object o = iterator.next(); .... } Zusammenfassung, Kernpunkte Objektorientierte Modellierung auf Entwurfsebene umgesetzt in Implementierungsebene am Beispiel von Java Fazit: Umsetzung nicht ganz einfach (teilweise sogar relativ aufwendig) Was kommt beim nächsten Mal? Persistente Objekte Java Data Objects (JDO)