Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

6.02.2006, Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 Generische Programmierung in Java.

Ähnliche Präsentationen


Präsentation zum Thema: "6.02.2006, Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 Generische Programmierung in Java."—  Präsentation transkript:

1 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 Generische Programmierung in Java

2 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 2 Generische Programmierung in der Vergangenheit ausschließlich unter Verwendung der Wurzelklasse Objekt Generics wurden mit der Version 1.5 zur generischen Programmierung in Java eingeführt Schablonen zur Klassen-, Schnittstellen- oder Methodenbeschreibung in denen verwendete Typen durch Typvariablen darstellt werden können unterstützen ein statisch typsicheres generisches Programmieren jedoch können nur generische Typen über Referenztypen und nicht über primitive Datentypen definiert werden generische Klassen und Methoden werden vom Compiler in Datenstrukturen übersetzt, die auf der Klasse Objekt basieren

3 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 3 Beispiel: Generisches Programmieren (bisher) class Node{ private Node left, private Node right; private Object info; Node(Object i, Node l, Node r) {info = i, right = r; left = l;} Node(Object i) {this(i, null, null);} Object getInfo(){return info;} void setInfo(Object i){info = i;} Node getLeft(){return left;} void setLeft(Node l){left = l;} Node getRight(){return right;} void setRight(Node r){right = r;} }

4 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 4 Probleme: Generische Programmierung (bisher) in mit Node aufgebauten Bäumen können Knoteninformationen von verschiedenartigen Datentypen sein Node n1 = new Node(´´foo´´); Node n2 = new Node( ); Node n3 = new Node(23, n1, n2); zum Auslesen von Knoteninformation ist eine nicht sichere Typkonvertierung notwendig String s = (String) n.getInfo();

5 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 5 Generische Klassen und Typen eine generische Klasse ist eine Klassendefinition, in der unbekannte Typen durch Typvariablen beschrieben werden ein generischer Typ ist die Instanzierung einer generischen Klasse mit einem konkreten Typargument Definition einer generischen Klasse class name {….} class name {….} Definition und Verwendung eines generischen Typs name d;

6 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 6 Beispiel: Generische Klasse Node class Node { private Node left, private Node right; private T info; Node(T i, Node l, Node r) {info = i, right = r; left = l;} Node(T i) {this(i, null, null);} T getInfo(){return info;} void setInfo(T i){info = i;} Node getLeft(){return left;} void setLeft(Node l){left = l;} Node getRight(){return right;}void setRight(Node r){right = r;} }

7 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 7 Beispiel: Generische Typen Node ns; ns = new Node (´´foo´´); Node ni; ni = new Node (1); Node ni; ni = new Node (´´foo´´);// Typfehler Node ni = new Node (1); Node ns = new Node (´´foo´´, ni, null); // Typfehler; String s = ns.getInfo(); // ohne Typcast Node = ns.getLeft();

8 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 8 Beispiel: Mehrere Typvariablen class Pair { private final T first; private final U second; Pair( T fst, U snd){ first = fst; second = snd; } T getFirst() { return first;} U getSecond(){ return second;} } Pair psi = new Pair (´´foo´´,1);

9 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 9 Generische Schnittstellen interface Taggable { void setTag(T tag); T getTag(); } class Someclass implements Taggable { private String tag; public void setTag(String t) {tag = t;} public String getTag() { return tag;} } class Node implements Taggable { private T tag; public void setTag(T t) {tag = t;} public T getTag() { return tag;} }

10 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 10 Typeinschränkung in generischen Klassenbeschreibungen kann die Zulässigkeit von Typargumenten durch extends und super eingeschränkt werden class Node {…} Typargumente in generischen Typen müssen zu etwaigen Typeinschränkungen kompatibel sein Node ni; //ok Node nd; //ok Node no; //Fehler! Node ns; // Fehler! Typvariablen können auch mehrere Typeinschränkungen haben Class classname

11 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 11 Beispiel: Mehrfache Typeinschränkung interface Timestamped{ String getTimestamp(); } interface Printable{ void print(); } class Node { … } class InfoDeluxe implements Timestamped, Printable{ String getTimestamp(){ … } void print(){ … } } Node nidlx; //okNode ns; //Fehler

12 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 12 Beispiel: Typeinschränkungen mit Typvariablen geordnete Bäume: class Node > { … } Node ns;//ok Node ni;//ok Node no;//Fehler eine Klasse, deren Oberklasse Comparable implementiert, wird nicht akzeptiert class Base implements Comparable { … } class Derived extends Base {... } Node nb; //ok Node nd; // Fehler

13 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 13 Generische Typen - Wildcardtypen Vererbungsbeziehung zwischen Typargumenten überträgt sich nicht auf generische Typen Node = new Node (23); //Fehler anstelle eines Typarguments kann ´´?´´ in Wildcardtypen eingesetzt werden alle generischen Typen der gleichen generischen Klassen sind kompatibel zum Wildcardtyp der Klasse Node n; n = new Node (23); //ok n = new Node (´´foo´´); //ok Aber: keine Vererbungsbeziehung

14 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 14 Wildcardtypen: Lese- und Schreibzugriffe in der Regel kein lesender und schreibender Zugriff auf Wildcardtypen Node n = Node (23); String s = n.getInfo(); //Fehler Integer i = n.getInfo(); //Fehler n.setInfo(1);//Fehler mit Ausnahme zweier Grenzfälle Object x = n.getInfo(); //ok n.setInfo(null); //ok

15 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 15 Wildcardtypen: Verwendung Wildcardtypen eignen sich für Situationen in denen das konkrete Typargument keine Rolle spielt class Util{ int nodesCount(Nodes n){ if(n == null) return 0; else return 1 + nodesCount(n.getLeft()) + nodesCount(n.getRight()); }

16 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 16 Wildcardtypen: Upper Bounds Einschränkung der Kompatibilität von Wildcardtypen mit dem Schlüsselwort extends Node n; kompatibel sind alle Typen, deren Typargument Number oder eine Unterklasse von Number ist n = new (23);//ok n = new (new Objekt());//Fehler kein schreibender Zugriff (ausser null-Referenzen) aber lesender Zugriff (liefert im Beispiel immer eine Unterklasse von Number)

17 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 17 Wildcardtypen: Lower Bounds Komplementäres Einschränken von Wildcardtypen mit dem Schlüsselwort super Node n; kompatibel sind alle Typen, deren Typargument Number oder eine Oberklasse von Number ist n = new (23);//Fehler n = new (new Objekt());//ok kein lesender Zugriff (ausser Objekt-Referenzen) aber schreibender Zugriff (liefert im Beispiel immer ein Argument vom Typ Number)

18 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 18 Generische Typen - Übersicht ArtLesenSchreibenkompatible Typargumente C erlaubt T C verboten alle C erlaubtverbotenB und Unterklassen C verbotenerlaubtB und Oberklassen

19 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 19 Generische Klassen – Behandlung durch Compiler generische Klassen werden unter Verwendung der Wurzelklasse Objekt in normale nicht-generische Klassen überführt Typvariablen und -einschränkungen werden aufgezeichnet und später in Form von Signaturbeschreibungen in den Bytecode eingefügt Typvariablen in spitzen Klammern werden gelöscht Typvariablen mit Typeinschränkungen werden durch die zuerst genannte Einschränkung ersetzt Typvariablen ohne Typeinschränkung werden durch Objekt ersetzt alle generischen Typen teilen sich eine einzige Implementierung ihrer Klasse

20 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 20 Beispiel: Übersetzung der Klasse Node class Node{ private Node left, private Node right; private Object info; Node(Object i, Node l, Node r) {info = i, right = r; left = l;} Node(Object i) {this(i, null, null);} Object getInfo(){return info;} void setInfo(Object i){info = i;} Node getLeft(){return left;} void setLeft(Node l){left = l;} Node getRight(){return right;} void setRight(Node r){right = r;} }

21 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 21 Generische Typen - Behandlung durch Compiler nach Überprüfung der korrekten Verwendung generischer Typen wird nicht-generischer Quellcode erzeugt, dabei werden Typargumente, einschließlich Wildcards, in spitzen Klammern gelöscht Typkonvertierungsoperationen eingeschoben, wo ein Wert eines Typarguments benutzt wird Generisches Programm: Node n = new Node (´´foo´´); String s = n.getInfo(); Erzeugtes nicht-generisches Programm: Node n = new Node(´´foo´´); String s = (String) n.getInfo();

22 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 22 Generische Typen - Rawtypes bei der Übersetzung von generischen Klassen entstehen sogenannte Rawtypes Rawtypes sind normale nicht-generische Klassen und lassen sich auch als solche benutzen Node n = new Node(´´foo´´); String s = (String) n.getInfo(); die korrekte Nutzung von Rawtypes unterliegt dem Programmierer der Compiler übersetzt zwar den Code, warnt aber gleichzeitig bei der Nutzung von Rawtypes uses unchecked or unsafe operations

23 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 23 Generische Typen - Grenzen keine Typvariablen in statischen Definitionen class Broken { static T data; // wird nicht übersetzt } keine dynamische Typprüfung von Typvariablen class Node { boolean hasMatchingType(Object x){ if(x instanceof T){// wird nicht übersetzt … }

24 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 24 Generische Typen - Grenzen wirkungslose Typkonvertierungen auf Typvariablen class Node { private T info; void setAny(Object x){info = (T) x;} // Warnung: unchecked cast to Type T } obwohl nur Warnungen vom Compiler gemeldet werden, können dynamische Laufzeitfehler die Folge sein Node ns = new Node (´´foo´´); ns.setAny(23); String s = ns.getInfo();// ClassCastException

25 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 25 Generische Typen - Grenzen keine Reihungen und Konstruktoraufrufe von Typvariablen class Node { private T info; private T[]a = new T[100]; // wird nicht übersetzt Node(){info = new T();} // wird nicht übersetzt } Erzeugung von Reihungen ist jedoch indirekt möglich class Node { private T[]a = (T[]) new Object[100]; // Warnung void set(int i, T t){a[i] = t;} T get(int i){return a[i];} } Typvariablen können keine Oberklassen bilden

26 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 26 Polymorphe Methoden Polymorphe (generische) Methoden sind ebenfalls Sprachmittel ab Java 1.5 Verwendung ist nicht auf generische Klassen beschränkt, sondern kann auch in gewöhnlichen Klassen erfolgen Deklaration [modifiers] rtype name([formPars]){...} Aufruf Reference. name([actPars]); wobei Reference für eine explizite Objekt- bzw. Klassenreferenz steht (ggf. ist auch this zu verwenden).

27 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 27 Beispiel: Polymorphe Instanzmethoden T vote(T x, T y, T z){ if(x.equals(y)) return x; if(y.equals(z)) return y; if(z.equals(x)) return z; return null; } String s = this. vote(“foo”,“bar”,“foo”); int i = this. vote(1,2,2);

28 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 28 Beispiel: Polymorphe Klassenmethoden class Util{ T[] makeArray(T… a){ return a; } String [] s = Util. makeArray(“1st”,“2nd”,“3rd”); Integer[] i = Util. vote(1,2,3);

29 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 29 Polymorphe Methoden: Typinferenz Typinferenz erlaubt das Weglassen von Typargumenten beim Aufruf polymorpher Methoden String s = vote(“foo”,“bar”,“foo”); int i = vote(1,2,2); beim Aufruf mit Argumenten unterschiedlichen Typs für die gleiche Typvariable wählt man die speziellste Unterklasse Number n = vote(1,3.14,2); // Ok Integer i = vote(1,3.14,2); // Fehler Double n = vote(1,3.14,2); // Fehler Object n = vote(1,3.14,2); // Ok wegen Kompatibilität

30 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 30 Polymorphe Methoden: Typeinschränkung wie bei generischen Typen können die Typargumente von polymorphen Methode einer Typeinschränkungen unterliegen > T median(T x, T y, T z){ …. } int i = median(1,3,2); // Ok Objec c = this. median(..); // Fehler

31 , Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 31 Polymorphe Methoden: Überladen Polymorphe Methoden dürfen nur überladen werden, wenn durch Übersetzung kein Konflikt zu anderen Methoden entsteht Object vote(Object x, Object y, Object z){..} T vote(T x, T y, T z){..} // nicht verträglich T vote(T x, T y, T z){..} // verträglich beim Überladen werden polymorphe Methoden erst dann berücksichtigt, wenn keine normalen Methoden passen void foo(T x){} //Passt nur wenn x keine Number ist void foo(Integer x){} void foo(Number x){}


Herunterladen ppt "6.02.2006, Dr. Wolfram Amme, Softwareentwicklung in Java, FSU Jena, WS 2005/06 Generische Programmierung in Java."

Ähnliche Präsentationen


Google-Anzeigen