Tipos geéricos (cot) Bruce Eckel, Thikig i Java, 4th editio, PreticeHall, New Jersey, cf. http://midview.et/books/tij4 Gilad Bracha, Geerics i the Java Programmig Laguage a.k.a The Geerics Tutorial, Julho de 2004 cf. http://java.su.com/j2se/1.5/pdf/geerics-tutorial.pdf jvo@ualg.pt José Valete de Oliveira 18-1 Sumário Noções chave Defiição e utilização de tipos geéricos Hierarquias de subtipos Tipos com limites Especificação UML Métodos geéricos Desevolvimeto de tipos geéricos: O quicksort revisitado Rasura Polimorfismo revisitado jvo@ualg.pt José Valete de Oliveira 18-2 1
Utilização de tipos geéricos Os tipos geéricos podem ser usados a declaração de:. Atributos;. Variáveis locais;. Parâmetros de métodos;. Tipos de retoro (de métodos). jvo@ualg.pt José Valete de Oliveira 18-3 Especificação de tipos geéricos em UML public class Stack <T> { ArrayList<T> items; public void push(t item) { // public T pop() { // 2
Métodos geéricos iterface Collectio<E> exteds Iterable<E> { <T>T[] toarray(t[] a); // public class MyCollectio<E> implemets Collectio<E> { //... public <T> T[] toarray(t[] a) { it i = 0; for(e elemet: this) a[i++] = elemet; retur a; jvo@ualg.pt José Valete de Oliveira 18-5 Utilizado o método geérico toarray Collectio<Iteger> ci = ew MyCollectio<Iteger>(); ci.add(1); Object[] ao = ew Object[ci.size()]; ao = ci.toarray(ao); jvo@ualg.pt José Valete de Oliveira 18-6 3
Istaciação, exemplos de public class Tst { public <T> T bypass(t obj) {retur obj; public void caller() { Strig s1 = abc"; Strig s2 = this.<strig>bypass(s1); Strig s3 = bypass(s1); // T -> Strig Object o1 = bypass(s1); // T -> Strig Object o2 = bypass((object) s1); // T -> Object Strig s4 = bypass((object) s1); // ERROR! Strig s5 = (Strig) bypass((object) s1); // OK agai Desevolvimeto de tipos geéricos jvo@ualg.pt José Valete de Oliveira 18-8 4
class Poit class Poit { private it x, y; public Poit(it ax, it ay) { class Poit { x=ax; private double x, y; y=ay; public Poit(double ax, double ay) { x=ax; public it getx() { retur x; y=ay; public it gety() { retur y; public double getx() { retur x; public double dist(poit p) { public double gety() { retur y; it dx = x p.getx(); it dy = y p.gety(); public double dist(poit p) { retur Math.sqrt(dx*dx+dy*dy); double dx = x p.getx(); double dy = y p.gety(); retur Math.sqrt(dx*dx+dy*dy); O que ós gostaríamos: Poit<Iteger> origi = ew Poit<Iteger>(0, 0); Poit<Double> pd = ew Poit<Double>(1.3, 2.4); jvo@ualg.pt José Valete de Oliveira 16-10 5
class Poit class Poit { private it x, y; public Poit(it ax, it ay) { class Poit { x=ax; private double x, y; y=ay; public Poit(double ax, double ay) { x=ax; public it getx() { retur x; y=ay; public it gety() { retur y; public double getx() { retur x; public double dist(poit p) { public double gety() { retur y; it dx = x p.getx(); it dy = y p.gety(); public double dist(poit p) { retur Math.sqrt(dx*dx+dy*dy); double dx = x p.getx(); double dy = y p.gety(); retur Math.sqrt(dx*dx+dy*dy); class Poit como um tipo geérico class Poit<T exteds Number> { private T x, y; public Poit(T ax, T ay) { x=ax; y=ay; public T getx() { retur x; public T gety() { retur y; 6
class Poit como um tipo geérico public double dist(poit<? exteds Number> p) { double dx = getx().doublevalue()- p.getx().doublevalue(); double dy = gety().doublevalue()- p.gety().doublevalue(); retur Math.sqrt(dx*dx+dy*dy); @Override public Strig tostrig() { retur x+ "@" + y; Usado potos geéricos public static void mai(strig[] args) { Poit<Iteger> origi = ew Poit<Iteger>(0,0); Poit<Double> pd = ew Poit<Double> (1.1, 2.5); System.out.pritl(origi + ".dist("+pd+"): "+ origi.dist(pd)); 7
Recallig quicksort jvo@ualg.pt José Valete de Oliveira 18-15 Ateriormete @SuppressWarigs( uchecked ) abstract class Quicksort { private Comparable[] data; /** pré-geerics **/ iterface Comparable { it compareto(object o); public fial void quicksort(comparable[] d) { data = d; quicksort(0, data.legth-1); /** quicksort method as the template method */ private fial void quicksort(it left, it right) { if (right <= left) retur; it i = partitio(left, right); quicksort(left, i-1); quicksort(i+1, right); jvo@ualg.pt José Valete de Oliveira 18-16 8
O que gostaríamos public class Mai { public static void mai(strig[] args) { List<Fractio> lst = ew ArrayList<Fractio>(); lst.add(ew Fractio(1, 7)); lst.add(ew Fractio(5, 2)); lst.add(ew Fractio(1, 2)); GQuicksort<Fractio> qs = ew ProbQuickSort<Fractio>(); qs.quicksort(lst); for(fractio f: lst) System.out.pritl (f); jvo@ualg.pt José Valete de Oliveira 18-17 O quicksort revisitado public abstract class GQuicksort<T exteds Comparable<T>> { private List<T> data; public fial void quicksort(list<t> d) { data = d; quicksort(0, data.size()-1); private fial void quicksort(it left, it right) { if (right <= left) retur; it i = partitio(left, right); quicksort(left, i-1); quicksort(i+1, right); jvo@ualg.pt José Valete de Oliveira 18-18 9
Ateriormete /** Call this i a subclass for swapig elemets i ad j */ protected fial void exchage(it i, it j) { Comparable tmp = data[i]; data[i] = data[j]; data[j] = tmp; /** Use this i subclasses to compare elemets x.compareto(y) aswer 0 if x ==y; -1 if x < y; 1 se x>y */ protected fial boolea less(it i, it j) { retur (data[i].compareto(data[j]) < 0); jvo@ualg.pt José Valete de Oliveira 18-19 O quicksort revisitado protected fial void exchage(iti, itj) { T tmp = data.get(i); data.set(i, data.get(j)); data.set(j, tmp); protected fial boolea less(it i, itj) { T di = data.get(i); T dj = data.get(j); retur (di.compareto(dj) < 0); jvo@ualg.pt José Valete de Oliveira 18-20 10
Ates class ProbQuickSort exteds Quicksort { @Override protected it partitio(it left, it right) { it last=left; it pp = left + (it) (Math.radom() * (right-left)); // pivot positio exchage(left, pp); for(it i=left+1; i <= right; i++) if (less(i, left)) exchage(i, ++last); exchage(left, last); retur last; jvo@ualg.pt José Valete de Oliveira 18-21 O quicksort revisitado class GProbQuickort<T extedscomparable<t>> exteds GQuicksort<T> { protected it partitio(itleft, it right) { it last=left; it pp = left + (it) (Math.radom() * (right-left)); // pivot positio exchage(left, pp); for(it i=left+1; i <= right; i++) if (less(i, left)) exchage(i, ++last); exchage(left, last); retur last; jvo@ualg.pt José Valete de Oliveira 18-22 11
Será que podemos usar esta classe atiga /** a pre-geerics versio */ class Fractio implemets Comparable { private it um, de; // public it compareto (Object o) { // /** pré-geerics **/ iterface Comparable { it compareto(objecto); jvo@ualg.pt José Valete de Oliveira 18-23 este cliete? public class Mai { public static void mai(strig[] args) { List<Fractio> lst = ew ArrayList<Fractio>(); lst.add(ew Fractio(1, 7)); lst.add(ew Fractio(5, 2)); lst.add(ew Fractio(1, 2)); GQuicksort<Fractio> qs = ew ProbQuickSort<Fractio>(); qs.quicksort(lst); for(fractio f: lst) System.out.pritl (f); jvo@ualg.pt José Valete de Oliveira 18-24 12
Vejamos public abstract class GQuicksort<T exteds Comparable<T>> { private List<T> data; // protected fial boolea less(it i, it j) { T di = data.get(i); T dj = data.get(j); retur (di.compareto(dj) < 0); jvo@ualg.pt José Valete de Oliveira 18-25 Relembremos /** pré-geerics **/ iterface Comparable { it compareto(object o); /** actualmete **/ iterface Comparable<T> { it compareto(t t); jvo@ualg.pt José Valete de Oliveira 18-26 13
Relembremos /** a pre-geerics versio */ class Fractio implemets Comparable { private it um, de; // public it compareto (Object o) { // jvo@ualg.pt José Valete de Oliveira 18-27 e se fizermos estas alterações? public abstract classgquicksort<t exteds Comparable<? super T>> { private List<T> data; // class GProbQuickort<T exteds Comparable<? super T>> exteds GQuicksort<T> { // jvo@ualg.pt José Valete de Oliveira 18-28 14
Ode estamos? Noções chave Defiição e utilização de tipos geéricos Hierarquias de subtipos Tipos com limites Especificação UML Métodos geéricos Desevolvimeto de tipos geéricos: O quicksort revisitado Rasura Polimorfismo revisitado jvo@ualg.pt José Valete de Oliveira 18-29 15