Polimorfismo Significato Varie famiglie Polimorfismo in java Polimorfismo

  • Slides: 11
Download presentation
Polimorfismo • Significato • Varie famiglie • Polimorfismo in java • Polimorfismo di Sottotipo:

Polimorfismo • Significato • Varie famiglie • Polimorfismo in java • Polimorfismo di Sottotipo: Apparato in Java • Polimorfismi particolari: container

Significato • Polimorfismo = avere più aspetti o forme • Generalizza struttura: - rispetto

Significato • Polimorfismo = avere più aspetti o forme • Generalizza struttura: - rispetto tipi coinvolti • meccanismo di astrazione • controllo: astrazioni procedurali • dati: tipi astratti • polimorfimo: - controllo: procedure polimorfe - dati: tipi polimorfi

Varie Famiglie • parametrico: - tipi generici (introducono relazioni generiche tra tipi) - esempio:

Varie Famiglie • parametrico: - tipi generici (introducono relazioni generiche tra tipi) - esempio: List(T) = null + T x List(T) public class List<T>{…}; • sottotipi - gerarchia di tipi (una solo relazione su tutti i tipi) - esempio: classe Object. List • ad hoc - strutture con piu significati - esempio: (nomi di) operatori overloaded

Polimorfismo in Java • sottotipi: - presente dalla prima definizione di Java - caratteristico

Polimorfismo in Java • sottotipi: - presente dalla prima definizione di Java - caratteristico degli OOL - discusso sul testo di riferimento • parametrico: - presente nell’ultima estensione (java 1. 5) - caratteristico dei funzionali - non lo consideriamo (per ora)

Polimorfismo di Sottotipo: Apparato in Java public class P_morphic{ //O: una P_morphic classe che

Polimorfismo di Sottotipo: Apparato in Java public class P_morphic{ //O: una P_morphic classe che astrae sul super_tipo A -- rep contiene riferimenti ad A public P_morphic(par) //E: inizializzazione di rep può richiedere A nei parametri public T 1 m 1(par 1) //può coinvolgere metodi di A …. public Tk mk(park) //può coinvolgere metodi di A

Liste omogenee e Liste ordinate public class Ordered. List{ public class List{ //O: liste

Liste omogenee e Liste ordinate public class Ordered. List{ public class List{ //O: liste omogenene, non vuote, modificabili di Object, …[x 1, . . , xn] private Object head; private List tail; //AF(c)=. . //I(c)=. . //O: liste omogenee, non vuote, ordinate, modificabili di Object … private comparable head; private Ordered. List up; private Ordered. List down; //AF(c)=. . //I(c)=. . private List(Object v, List L) //E: crea lista interna [v, x 1, …, xn] con AF(L)= [x 1, …, xn] {head=v; tail=L; } public void cons(Object v) throws CCE, NPE //E: se v è null solleva eccezione. NPE, se tail è non null e ha tipo diverso da // quello di v allora solleva eccezione CCE, altrimenti aggiungi come primo // elemento {if (v==null) throw new NPP(“…”); if (head==null) {head=v; return; } if (head. get. Class()!=v. get. Class())) throw new CCE(“…”); tail=new List(head, tail); head=v; } public void drop() //E: rimuove il primo elemento se presente altrimenti nulla public Object head() throws ELE //E: restituisce il primo elemento se presente, altrimenti Emp. List. Exc Esattamente stesso tipo Un sottotipo di quello di head: head. get. Class()). is. Instance(v) private Ordered. List() //E: crea lista indefinita -- non accessibile {} public void cons(comparable v) throws CCE, NPE //E: se v è null solleva eccezione. NPE, se tail è non null e non è confrontabile con // v allora solleva eccezione CCE, altrimenti aggiungi ordinatamente {if (v==null) throw new NPP(“…”); if (head==null) {up=new ordered. List(); down=new Ordered. List(); head=v; return; } int n=head. compare. To(v); n= if(n==0 | n>0) up. cons(v); else down. cons(v); } public void drop() //E: rimuove il primo elemento se presente altrimenti nulla public Object head() throws ELE //E: restituisce il primo elemento se presente, altrimenti Emp. List. Exc

Situazioni particolari: Container public class SList{ //O: liste omogenene, modificabili di Object occorrenti una

Situazioni particolari: Container public class SList{ //O: liste omogenene, modificabili di Object occorrenti una sola volta private Object head; private List tail; //AF(c)=. . //I(c)=. . private List(Object v, List L) //E: crea lista interna [v, x 1, …, xn] con AF(L)= [x 1, …, xn] {head=v; tail=L; } public void cons(Object v) throws CCE, NPE, DOE //E: se v è null solleva eccezione. NPE, se tail è non null e ha tipo diverso da // quello di v allora solleva eccezione CCE, se ha valore uguale a quello di v // allora solleva eccezione DOE, altrimenti aggiungilo come primo elemento. {if (v==null) throw new NPP(“…”); if (head == null) {head =v; return; } if (head. get. Class() != v. get. Class()) throw new CCE(“…”); if (occur(v)) throw new DOE(“…”); tail=new List(head, tail); head=v; } public void drop() //E: rimuove il primo elemento se presente altrimenti nulla public Object head() throws ELE //E: restituisce il primo elemento se presente, altrimenti Emp. List. Exc private boolean occurs(Object v) //R: v!=null & head!=null => tail. get. Class() == v. get. Class() //E: calcola true se v occorre in this, false altrimenti. {if (v. equals(head)) return true; if (tail == null) return false; return tail. occurs(v); } Applichiamola: Valutiamo le sequenze Integer n 1 = new Integer(3); Integer n 2 = new Integer(3); Integer n 3 = new Integer(3); cons(n 1, cons(n 2, cons(3, empty())))) ================= Vector v 1 = new Vector(); Vector v 2 = new. Vector(); Vector v 3 = new Vector(); cons(n 1, cons(n 2, cons(3, empty()))) ==================== Set i 1 = new Set(); Set i 2 = new Set(); cons(i 1, cons(i 2, empty())) ==================== Fun f 1 = new Fun(); Fun f 2 = new Fun(); cons(f 1, cons(f 2, empty()));

Situazioni particolari: Container public class SList{ …… //O: liste omogenene, modificabili di Object occorrenti

Situazioni particolari: Container public class SList{ …… //O: liste omogenene, modificabili di Object occorrenti una sola volta //O: …. Usiamo containers con cui wrap-unwrap gli objects private Object head; private List tail; //AF(c)=. . //I(c)=. . private List(Object v, List L) //E: crea lista intermedia [v, , x 1, …, xn] con AF(L)= [x 1, …, xn] {head=v; tail=L; } private Container head; private List tail; … … public void cons(Container v) throws CCE, NPE, DOE //E: se v è null solleva eccezione. NPE, se tail è non null e ha tipo diverso da //quello di v allora solleva eccezione CCE, se ha valore uguale a quello di v // allora solleva eccezione DOE, altrimenti aggiungilo come primo elemento. {…} public void cons(Object v) throws CCE, NPE, DOE public void drop() //E: se v è null solleva eccezione. NPE, se tail è non null e ha tipo diverso da // quello di v allora solleva eccezione CCE, se ha valore uguale a quello di v // allora solleva eccezione DOE, altrimenti aggiungilo come primo elemento. //E: rimuove il primo elemento se presente altrimenti nulla public Object head() throws ELE {if (v==null) throw new NPP(“…”); if (head == null) {head =v; return; } if (head. get. Class() != v. get. Class()) throw new CCE(“…”); if (occur(v)) throw new DOE(“…”); tail=new List(head, tail); head=v; } private boolean occurs(Object v) public void drop() //E: rimuove il primo elemento se presente altrimenti nulla public Object head() throws ELE //E: restituisce il primo elemento se presente, altrimenti Emp. List. Exc private boolean occurs(Object v) //R: v!=null & head!=null => tail. get. Class() == v. get. Class() //E: calcola true se v occorre in this, false altrimenti. {if (v. equals(head)) return true; if (tail == null) return false; return tail. occurs(v); } //E: restituisce il primo elemento se presente, altrimenti Emp. List. Exc //R: v!=null & head!=null => head. get. Class() == v. get. Class() //E: calcola true se v occorre in this, false altrimenti. {…} public class container{ //O: Container sono immutable, contengono un singolo oggetto. Due // container sono equals se e solo se contengono lo stesso oggetto private Container el; //AF(c)=AF(c. el) //I(c)=el≠null; public container(Object v) //E: crea container per v {el=(Fun)v; } public Object get() //E: unwrapping {return el; } public boolean equals(Object v) {if(!( Class. for. Name(“Container”)). is. Instance(v)) return false; return (el == (Container) v. el); }

Container: una tabellina effects == equals modificabili Non modificabili Container (con solo modificabili) puntatori

Container: una tabellina effects == equals modificabili Non modificabili Container (con solo modificabili) puntatori OK No No Stato (rep) No OK OK public class Fun. Containers extends Containers{ public class Set. Containers extends Containers{ //O: Fun. Container sono Containers. Due Fun. Containers sono // equals se e solo se contengono lo stesso Fun //O: Set. Container sono Containers. Due Set. Containers sono // equals se e solo se i Set contenuti sono strutturalmente identici private Fun el; private Set el; //AF(c)=AF(c. el) //I(c)=el≠null; public container(Object v) throws CCE, NPE //E: crea container per v {el=(Fun)v; } //E: crea container per v {el=(Set)v; } public Object get() //E: unwrapping {return el; } public boolean equals(Object v) {Class T= Class. for. Name(“Fun. Containers”); if(!(T. is. Instance(v)) return false; return (el == (Fun) v. el. get()); } {Class T= Class. for. Name(“Set. Containers”); if(!(T. is. Instance(v)) return false; return (el. equals((Set) v. el. get())); } Fun sono modificabili Set sono non. Modificabili

Situazioni particolari: Related Subtype public class P_morphic{ //O: una P_morphic classe che astrae sul

Situazioni particolari: Related Subtype public class P_morphic{ //O: una P_morphic classe che astrae sul super_tipo A -- rep contiene riferimenti ad A public P_morphic(par) // inizializzazione di rep può richiedere A nei parametri public T 1 m 1(par 1) //può coinvolgere metodi di A …. public Tk mk(park) //può coinvolgere metodi di A Quando un supertipo A non c’è? - Creiamo una gerarchia di tipi correlati - Definiamo P_morphic su tale gerarchia

Situazioni particolari: Adder public class Sum. Set{ public class Int. Adder implements Adder{ //O:

Situazioni particolari: Adder public class Sum. Set{ public class Int. Adder implements Adder{ //O: mutable set di oggetti con operazione sum degli oggetti dello // insieme. Tali oggetti sono related subtype di un interfaccia adder //O: una related subtype per Integer con operazioni add, sub, zero private Integer a; public Int. Adder() private Adder a; // oggetto del related subtype private Vector els; // per gli elementi Private Object s; // somma degli elementi //E: sceglie 0 per a {a = new Integer(0); } //AF(c)={c. els. get(i)|0≤i<c. els. size()} //I(c)= c. els!=null && c. a. equals(c. a. sum(c. a, c. a)) && (0≤i<c. els. size()) c. a. get. Class()==c. els. get(i). get. Class() && s= s= 0≤i<c. els. size()c. a. sum(c. a, c. els. get(i)) public Object add(Object x, Object y) throws CCE, NPE //E: calcola oggetto somma se esiste //E: crea insieme vuoto {if (x==null || y==null) throw new NPE(“…”); if (!is. Integer(x) || !is. Integer(y) throw new CCE(“…”); return new Integer((Integer)x. int. Value()+ ((Integer)y. int. Value())} {els=new Vector(); a=p; s=a. zero(); } //E: calcola oggetto sottrazione se esiste public Sum. Set(Adder p)throws NPE public Object sub(Object x, Object y) throws CCE, NPE //M: this // E: aggiunge v e modifica la somma {if (x==null || y==null) throw new NPE(“…”); if (!is. Integer(x) || !is. Integer(y) throw new CCE(“…”); return new Integer((Integer)x. int. Value()-((Integer)y. int. Value())} {if (!is. In(x)) {s=a. add(s, x); els. add(x); } } //E: calcola oggetto sottrazione se esiste public void insert(Object x) throws CCE, NPE public Object zero() {return a; } private boolean is. Integer(Object x){ return( x. get. Class()==a. get. Class()} public Object sum() //E: somma degli elementi {return s; } } public boolean is. In(x) throws CCE, NPE //E: true see x appartiene all’insieme //E: calcola true se v occorre in this, false altrimenti. {if (v==null) throw NPE(“…”); if (a. get. Class()!=x. get. Class()) throw new CCE(“…”); int i; for(i=0; i<els. size() && !x. equals(els. get(i)); i++); return (i!=els. size()); }…; } public class Vect. Adder extends Adder{ //O: una related subtype per Vectors con operazioni add, sub, zero private Vector a; public Object Vect. Adder() …