Generiche Programmieren homa Röfer Generiche Klaen und Interface Generiche ypen ypebound Wildcard-ypen Überetzung genericher Klaen Grenzen genericher ypen Polymorphe Methoden
Rückblick Vererbung Pakete java.lang.sytem.out.println("hallo") Paket Paket Klae ttribut Methode Vererbung Mehrfache Erben Speicherlayout uper fn1 fn2 fn3 Frühe/päte Binden btrakte Klaen / Schnitttellen uper fn1() fn1() fn1 fn2() fn2() fn2 B B extend extend fn2() fn2() fn3() fn3() : : a a (); (); a.fn1(); a.fn1(); b b B(); B(); b.fn1(); b.fn1(); b.fn2(); b.fn2(); b.fn3(); b.fn3(); // // Kompilierfehler! Kompilierfehler! abtract Geraet abtract Geraet int eriennummer; abtract int eriennummer; ein(); abtract ein(); interface Printable interface Printable print(); print(); PI-1: Generiche Programmieren 2
Motivation ; ; ( ( info info ( ( info info r; r; ; ; ; ; etinfo( etinfo( info info Problem: Zugriff nicht yp-icher! 1 2 3 4 5 6 n1 n1 ("foo"); ("foo"); n2 n2 (3.14); (3.14); n0 n0 (23, (23, n1, n1, n2); n2); () () n1.; n1.; PI-1: Generiche Programmieren 3
Generiche Klaen Definition Generiche Klaen haben ypvariablen, die im Klaenrumpf verwendet werden können <> ypvariablen können (fat) wie ein normaler yp benutzt werden Mehrere ypvariablen ind möglich <> <> <> <> ; ; Pair<, Pair<, U> U> firt; firt; U U econd; econd; Pair( Pair( t, t, U U u) u) firt firt t; t; econd econd u; u; getfirt() getfirt() firt; firt; U U getsecond() getsecond() econd; econd; ( ( info info ( ( <> <> <> <> info info r; r; <> <> ; ; <> <> ; ; etinfo( etinfo( info info PI-1: Generiche Programmieren 4
Generiche ypen Generiche Interface Begriffe interface interface aggable<> aggable<> etag( etag( tag); tag); getag(); getag(); Eine generiche Klae it eine Klaendefinition, in der unbekannte ypen durch ypvariablen vertreten ind. Für generiche Interface gilt entprechende <> info Ein genericher yp it eine ypangabe, in der eine generiche Klae mit einem konkreten ypargument verehen wird <Integer> n <Integer>(23); implement implement aggable<> aggable<> tag; tag; public public etag( etag( t) t) tag tag t; t; public public getag() getag() tag; tag; Pair<Integer, > p Pair<Integer, >(28359, "Bremen"); PI-1: Generiche Programmieren 5
ypebound Motivation Manchmal ollen nicht alle ypen für die Belegung der ypvariablen zuläig ein, z.b. wenn e pezielle nforderungen an die ypargumente gibt Diee können durch ypebound fetgelegt werden < extend Number> Definition Ein ypebound bedeutet it kompatibel zu ypebound können Klaen und auch Interface ein uch bei Interface wird hier extend verwendet E kann mehrere ypebound pro ypvariable geben Sie werden durch & aufgezählt werden, z.b. < extend & B & C> Erter ypebound kann Klae oder Interface ein, weitere können nur Interface ein Ein ypebound legt die Mindetanforderungen für eine ypvariable fet Dadurch wird auch definiert, wa man von dieem yp an Funktionalität erwarten kann ypebound können wiederum die ypvariable enthalten < extend Comparable<>> PI-1: Generiche Programmieren 6
Wildcard-ypen Fragetellung Jede generiche Klae erzeugt viele generiche ypen <> erzeugt <Number>, <Integer>, <Double> Wie tehen die von einer generichen Klae erzeugten ypen zueinander? Vererbung genericher ypen Eine bleitungbeziehung zwichen ypargumenten überträgt ich nicht auf die generichen ypen <Number> n <Integer>(23); // Fehler! int int count(<?> count(<?> n) n) Die wird al Invarianz bezeichnet if(n if(n null) null) Generiche ypen können unbetimmte 0; 0; ele ypargumente nennen ele <?> nx; 1 1 + nx <>("foo"); + count(n.) count(n.) + nx <Integer>(1); + count(n.); count(n.); nx <Double>(3.14); Wildcard (Joke bei ypangaben PI-1: Generiche Programmieren 7
Covarianz genericher ypen Motivation Zu einem Wildcard-yp mit ypargument? ind alle generichen ypen der betreffenden generichen Klae kompatibel Manchmal möchte man die durch einen og. Upper-ypebound einchränken <? extend Number> nb; nb <Integer>(23); nb <>( ()); // Fehler! Definition Mit Upper-ypebound wird Covarianz für generiche ypen eröffnet llgemein gilt C<> it kompatibel zu C<? extend B>, wenn it kompatibel zu B Problem uch rray kennen Covarianz, aber tatiche ypprüfung veragt Number[ ] a Integer[23]; a[0] Double(3.14); // rraystoreexception Löung bei generichen ypen: nur Leen erlaubt <? extend Number> nb <Integer>(23); Number n nb.; nb.etinfo(3.14); // Fehler! PI-1: Generiche Programmieren 8
Contravarianz genericher ypen Motivation Zu einem Wildcard-yp mit ypargument? ind alle generichen ypen der betreffenden generichen Klae kompatibel Manchmal möchte man die durch einen og. Lower-ypebound einchränken <? uper Number> nb; nb <>( ()); nb <Integer>(23); // Fehler! Definition Mit Lower-ypebound wird Contavarianz für generiche ypen eröffnet llgemein gilt C<> it kompatibel zu C<? uper B>, wenn B it kompatibel zu Nur Schreibzugriff <? uper Number> nb <>( ()); nb.etinfo(1); Number n nb.; // Fehler! PI-1: Generiche Programmieren 9
Zuammenfaung Varianzen Invarianz Verchiedene generiche ypen ind zueinander inkompatibe unabhängig von der Kompatibilität ihrer ypargumente Bivarianz Wildcard-ypen ohne Einchränkung (C<?>) ind immer zueinander kompatibel Covarianz Zu Wildcard-ypen mit Upper-ypebound (C<? extend B>) ind alle generichen ypen kompatibe deren ypargument zu B kompatibel it Contravarianz Zu Wildcard-ypen mit Lower-ypebound (C<? uper B>) ind alle generichen ypen kompatibe zu deren ypargument B kompatibel it yp Leen Schreib. Kompatible ypargumente Invarianz C<> ja ja Bivarianz C<?> nein nein lle Covarianz C<? extend B> ja nein B und abgeleitete ypen Contravarianz C<? uper B> nein ja B und Baitypen PI-1: Generiche Programmieren 10
Überetzung genericher Klaen natz Generiche Datentypen werden in Java auchließlich vom Compiler verarbeitet Da Laufzeitytem weiß nicht von generichen Datentypen Überetzung Mit ype-eraure wird genericher Code mit ypvariablen und ypargumenten auf normalen, nicht-generichen Java-Quelltext reduziert Der nicht-generiche Java-Quelltext wird weiterverarbeitet wie biher u jeder generichen Klae wird eine nicht-generiche Klae generiert und in eine.-datei überetzt In C++ wird dagegen jede Intanziierung einer Klae mit ypargumenten getrennt überetzt Dadurch langamere Überetzen und größere Kompilate, aber beere Optimierungmöglichkeiten und weniger Einchränkungen PI-1: Generiche Programmieren 11
ype-eraure Bei der ype-eraure genericher Klaen werden yp-variablen in pitzen Klammern gelöcht Vorkommen von ypvariablen mit einem oder mehreren ypebound durch den einzigen bzw. erten ypebound eretzt Vorkommen von ypvariablen ohne ypebound durch eretzt Bei der ype-eraure der Verwendung genericher Klaen werden die yp-korrektheit tatich geprüft (d.h. zum Überetzungzeitpunkt) ypargumente müen allen ypebound genügen generiche ypen müen auch untereinander korrekt verwendet werden, inbeondere bei Wildcard-ypen ypargumente, einchließlich Wildcard, in pitzen Klammern gelöcht ypecat eingechoben, wo der Wert eine ypargument benutzt wird PI-1: Generiche Programmieren 12
ype-eraure Beipiel <> <> <> <> ; ; Generiche Klae ( ( info info ( ( <> <> <> <> info info r; r; <> <> ; ; <> <> ; ; etinfo( etinfo( info info <> <> n n <>("foo"); <>("foo"); n.; n.; ; ; Nach ype-eraure (Rawtype) ( ( info info ( ( info info r; r; ; ; ; ; etinfo( etinfo( info info n n ("foo"); ("foo"); () () n.; n.; PI-1: Generiche Programmieren 13
ype-eraure Beipiel <> <> <> <> ; ; Generiche Klae ( ( info info ( ( <> <> <> <> info info r; r; <> Rawtype <> laen ich auch ; ; <> direkt <> benutzen, aber die ; ; ypicherheit etinfo( etinfo( geht info verloren info (Compiler-Warnung) <> <> n n <>("foo"); <>("foo"); n.; n.; ; ; Nach ype-eraure (Rawtype) ( ( info info ( ( info info r; r; ; ; ; ; etinfo( etinfo( info info n n ("foo"); ("foo"); () () n.; n.; PI-1: Generiche Programmieren 14
Grenzen genericher ypen (1) Primitive ypargumente <int> ni <int>(23); // Fehler! ber: <Integer> ni <Integer>(23); // utoboxing Statiche Elemente Broken<> tatic data; // Fehler! Grund: lle Klaen Broken<> teilen ich da Klaenattribut data. Welchen yp oll e haben? Dynamiche ypprüfung <> boolean icompatible( o) o intanceof ; // Fehler! ype-eraure: o intanceof o intanceof ypecat <> etinfo( o) info () o; // Sinnlo ype-eraure: () o () o Compiler erzeugt: warning: unchecked cat of type PI-1: Generiche Programmieren 15
Grenzen genericher ypen (2) Kontruktoraufrufe <> () info (); // Fehler Woher oll Java wien, da einen Standard-Kontruktor hat? Beipiel: <Integer> ni <Integer>(); uweg: <> ( info <Integer> ni <Integer>(23); Generiche Baitypen import java.util.date; imetamped<> extend Date timetamp Date(); // Fehler Generiche Klae mu Kontruktor der Baiklae aufrufen können. Dieer kann hier aber nicht zur Kompilierzeit ermittelt werden! Exception UniveralException<> extend Exception reaon; // Fehler Generiche ypen können nicht für Exception verwendet werden, da da Fangen mit catch auf dem Ermitteln de yp de geworfenen Objekt baiert. Dieer geht aber bei der ype-eraure verloren. Compiler erzeugt: a generic may not extend java.lang.hrowable PI-1: Generiche Programmieren 16
Grenzen genericher ypen (3) rray von ypvariablen Container<> [] a [100]; uweg: Container<> [] a ([]) [100]; // Warnung Compiler erzeugt ue unchecked or unafe operation Man kann trotzdem typichere Klaen ertellen: Container<> Container<> [] [] a a ([]) ([]) [100]; [100]; // // Warnung Warnung et(int et(int t) t) a[i] a[i] t; t; get(int get(int a[i]; a[i]; PI-1: Generiche Programmieren 17
Generiche (polymorphe) Methoden Definition Polymorphe Methoden ind unabhängig von generichen ypen Sie können auch in nicht-generichen Klaen definiert werden Klaen- und Objektmethoden owie Kontruktoren können polymorph ein ufruf thi.<>vote("foo", "foo","bar"); int i thi.<integer>vote(1,2,2); thi.<>vote(1,2,2); // Fehler! yp-inferenz vote("foo", "foo","bar"); <> <> vote( vote( x, x, y, y, z) z) if(x.equal(y)) if(x.equal(y)) x; x; ele ele if(y.equal(z)) if(y.equal(z)) y; y; ele ele if(z.equal(x)) if(z.equal(x)) z; z; ele ele nul nul ypparameter werden automatich mit dem unterten gemeinamen yp belegt Double d vote(1, 3.14, 1); // Fehler! entpricht Double d vote( Integer(1), Double(3.14), Integer(1)); // Fehler! Number n vote(1, 3.14, 1); // ok PI-1: Generiche Programmieren 18
Funktionen höherer Ordnung Definition Funktionen höherer Ordnung bekommen elbt Funktionen al Parameter In Java ind Funktionen al Parameter nicht möglich, wohl aber Objekte von Klaen, die betimmte Interface implementieren Beipiel: Faltung Eine Faltung faltet eine Lite (oder ein rray) zu einem einzigen Wert zuammen Dazu wird eine binäre Funktion der Reihe nach auf alle Elemente angewendet In Hakell: foldl (+) 0 [1,2,3,4,5] ((((0 + 1) + 2) + 3) + 4) + 5 interface interface FoldlFn<, FoldlFn<, B> B> fn( fn( a, a, B B b); b); <, <, B> B> foldl(foldlfn<, foldl(foldlfn<, B> B> f, f, a, a, B[] B[] b) b) for(b for(b b0 b0 : : b) b) a a f.fn(a, f.fn(a, b0); b0); a; a; concat([] concat([] object) object) foldl( foldl( FoldlFn<, FoldlFn<, >() >() public public fn( fn(,, o) o) + + o.to(); o.to();,, "", "", object); object); PI-1: Generiche Programmieren 19