Fondamenti di Informatica 1 Prof. B.Buttarazzi A.A. 2010/2011
Sommario Paradigma OO Incapsulamento Polimorfismo e Overloading Ereditarietà e Overriding Esercizi svolti Esercizi proposti
Paradigma OO Le fasi fondamentali del POO Definire le classi cioè approssimazioni di oggetti reali che hanno un ruolo nel problema da risolvere, limitatamente agli aspetti interessanti; Implementando l information hiding per il quale ogni classe "nasconde alcune informazioni che sono utili solamente allo svolgimento dei suoi compiti) esponendo un interfaccia, cioè l insieme di dati (proprietà) e di comportamenti (metodi) che sono visibili nel resto del programma. Per semplificare la programmazione se serve potrà essere utilizzato il Polimorfismo dei metodi che attraverso l'overloading dei metodi che consente ad una classe di avere più metodi con lo stesso nome ma con parametri differenti
Si dice che la Sottoclasse estende la Superclasse. Ereditarietà L'ereditarietà è un meccanismo fondamentale per il riutilizzo del codice nella programmazione a oggetti. Infatti grazie a questo meccanismo è possibile estendere e potenziare classi già esistenti. In Java si usa l ereditarietà quando occorre definire una classe i cui oggetti realizzano delle funzionalità aggiuntive (ovvero hanno una struttura più ricca di quella di una classe già definita) La classe più "generale" (quella preesistente) si dice Superclasse. La nuova classe più "specializzata" che eredita i campi e i metodi dalla classe preesistente viene detta Sottoclasse.
Esercizio Creare una classe di nome Persona con le variabili di istanza: nome, cognome di tipo stringa. La classe deve contenere un costruttore parametrico; i metodi get Nome e getcognome.
Esempio class Persona class Persona private String nome; private String cognome; public Persona(String nome,string cognome) this.nome=nome; this.cognome=cognome; public String getnome() return nome;...
Esercizio Costruire una sottoclasse di Persona, chiamata Studente, che contiene le variabili di istanza: matricola ed esami, che registra il numero di esami sostenuti, e devono essere entrambe di tipo intero. La sottoclasse deve contenere un costruttore parametrico ed i metodi set e get.
class Studente extends Persona private int esami; private int matricola; public Studente( String nome, String cognome, int matricola ) super (nome,cognome); this.matricola=matricola; public int getesami() return esami; public void setesami( int esami ) this.esami=esami; public int getmatricola() return matricola; costruttore della classe genitrice
class Studente extends Persona private int esami; private int matricola; public Studente( String nome, String cognome, int matricola ) super (nome,cognome); this.matricola=matricola; public int getesami() return esami; public void setesami( int esami ) this.esami=esami; public int getmatricola() return matricola; costruttore della classe genitrice L espressione super(...) invoca il costruttore della classe genitrice (nel nostro caso Persona), quindi deve avere i parametri attuali corrispondenti in numero e tipo a quelli formali.
Relazione tra ereditarietà ed incapsulamento L incapsulamento rappresenta una tecnica per rendere robusto il programma mentre l ereditarietà è considerata come un ottimo strumento di sviluppo e semplificazione; Per utilizzare entrambi i paradigmi andranno però fatte alcune considerazioni. Ereditando una classe nella quale viene applicato l incapsulamento, i suoi campi privati sarebbero accessibili solo attraverso l utilizzo dei metodi set e get!. Per ovviare a questa limitazione esiste la possibilità di utilizzare il modificatore di accesso protected; una variabile dichiarata protected in una certa classe sarà accessibile da tutte le classi dello stesso package e da classi di package diversi che estenderanno la classe più generale.
Esempio class Persona class Persona protected String nome; Nuovo tipo di protected String cognome; modificatore di public Persona(String nome,string cognome) visibilità! this.nome=nome; this.cognome=cognome; public String getnome() return nome; public String getcognome() return cognome;
class Studente extends Persona protected int esami; protected int matricola; public Studente( String nome, String cognome, int matricola ) super (nome,cognome); this.matricola=matricola; public int getesami() return esami; public void setesami( int esami ) this.esami=esami; public int getmatricola() return matricola; Richiama il metodo costruttore della classe genitrice Nuovo tipo di modificatore di visibilità!
Il modificatore di accesso protected: rende accessibile un campo a tutte le sottoclassi, presenti e future costituisce perciò un permesso di accesso valido per ogni possibile sottoclasse che possa essere definita.
Modificatori di accesso private disponibile solo dall ambito della stessa classe protected:disponibile nell ambito delle sottoclassi public: disponibile per qualsiasi altra classe default disponibile per qualsiasi altra classe appartenente allo stesso package
La parola chiave super nella forma super(...), invoca un costruttore della classe base nella forma super.val, consente di accedere al campo val della classe base (sempre che esso non sia private) nella forma super.metodo(), consente di invocare il metodo metodo() della classe base (sempre che esso non sia private)
Pseudo-variabili Nei metodi è possibile utilizzare le pseudo-variabili this e super this fa riferimento all istanza stessa si usa per evitare ambiguità class Ciclista extends Persona Bicicletta bici; boolean dimmisetua(bicicletta bici) return this.bici = bici; super fa riferimento all istanza stessa come se appartenesse alla superclasse si usa per evitare ambiguità e per specializzare metodi class ContoCorrente float saldo; void deposita(float somma) saldo += somma; class ContoAziendale RegistroCassa registro; void deposita(float somma) super.deposita(somma); registro.annotaentrata(somma);
Polimorfismo In merito al polimorfismo dei metodi, possiamo distinguere i concetti di overload ed override. Con overload si intende la possibilità, consentita al programmatore, di definire, in una stessa classe, più metodi col medesimo nome, ma firma differente. Ciò è utile quando si desidera definire più metodi che possiedano la medesima funzionalità, ma con differente campo di applicazione (cioè con una diversa lista di parametri). Per quanto riguarda l override, invece, si intende la caratteristica delle classi derivate (ereditarietà) di poter ridefinire un metodo pubblico ereditato dalla superclasse.
Overriding L'overriding rappresenta una importante risorsa della programmazione ad oggetti, indica la caratteristica delle sottoclassi di poter ridefinire un metodo ereditato da una superclasse. Ovviamente non esisterà override senza ereditarietà.
Overriding:esempio Class Impiegato public class Impiegato proteced String nome; protected double stipendio; protected Date datanascita; public String getdettagli() return "Nome: " + nome + "\n" + "Stipendio: " + stipendio;
Overriding:esempio Class Impiegato public class Dirigente extends Impiegato proteced String dipartimento; public String getdettagli() return "Nome: " + nome + "\n" + "Stipendio: " + stipendio + "\n" + "Dirigente del Dipartimento: " + dipartimento; Quando viene istanziato un oggetto di classe Dirigente ed invocato il metodo getdettagli(), verrà automaticamente richiamato il metodo ridefinito (overridden) nella stessa classe Dirigente
Nell override è necessario rispettare le seguenti regole: Il metodo ridefinito nella sottoclasse deve possedere la medesima firma di quello da riscrivere (altrimenti si opererebbe un overload); e lo stesso tipo di ritorno; lo stesso specificatore d accesso.
Esercizio Creare una classe di nome Persona con le variabili di istanza: cognome,nome, codice fiscale e città di tipo stringa. La classe deve contenere un costruttore di default che inizializzi le variabili di istanza con NULL; un costruttore parametrico; i metodi set e get ed un metodo chiamato AnnoNascita che a partire dal codice fiscale ricavi e restituisca l'anno di nascita di una persona.
Esercizio Creare un'applicazione Java che istanzi un oggetto della classe Persona e ne visualizzi in seguito nome, cognome ed anno di nascita.
Costruire una sottoclasse di Persona, chiamata Stagista, che contiene 2 variabili di istanza entrambe di tipo intero: numeropresenze, che registra il numero di ore di presenza, e numeroidentificativo Esercizio La sottoclasse deve contenere un costruttore parametrico ed i metodi set e get.
Esercizio Creare tre oggetti di tipo Stagista memorizzarli in un array e visualizzare lo Stagista più giovane.
Soluzione Creare una classe di nome Persona con le variabili di istanza: cognome,nome, codice fiscale e città di tipo stringa. class Persona protected String cognome; protected String nome; protected String codicefiscale; protected String citta;
La classe deve contenere un costruttore di default che inizializzi le variabili di istanza con NULL; un costruttore parametrico; i metodi set e get ed Soluzione
Soluzione Persona() cognome=null; nome=null; codicefiscale=null; citta=null; Persona (String c,string n,string cf,string ct) cognome=c; nome=n; codicefiscale=cf; citta=ct; public void setcognome(string cg) cognome=cg; public String getcognome() return cognome; public void setnome(string nm) nome=nm; public String getnome() return nome; public void setcodicefiscale(string cdf) codicefiscale=cdf; public String getcodicefiscale() return codicefiscale; public void setcitta(string ctt) citta=ctt; public String getcitta() return citta;
Soluzione La classe deve contenere un metodo chiamato AnnoNascita che a partire dal codice fiscale ricavi e restituisca l'anno di nascita di una Persona. public String AnnoNascita() String anno; anno=codicefiscale.substring(6,8); //metodo che permette di sottoscrivere una stringa return anno;
Esercizio Creare un'applicazione Java che istanzi un oggetto della classe Persona e ne visualizzi in seguito nome, cognome ed anno di nascita.
class UsaPersona public static void main(string[] args) Persona surname=new Persona("Rossi","Marzio","rssmrz80e65041u","Roma ); String c=surname.getcognome(); String n=surname.getnome(); String an=surname.annonascita(); int anno=integer.parseint(an); System.out.println("cognome della persona:"+c); System.out.println("il nome della persona:"+n); System.out.println("l'anno di nascita della persona:"+anno);
Esercizio Costruire una sottoclasse di Persona, chiamata Stagista, che contiene 2 variabili di istanza di tipo intero: numeropresenze, che registra il numero di ore di presenza, e numeroidentificativo che registra il numero identificativo. La sottoclasse deve contenere un costruttore parametrico ed i metodi set e get.
Soluzione class Stagista extends Persona private int numeropresenze; private int numeroidentificativo; Stagista (String c,string n,string cd,string ct,int np,int id) super(c,n,cd,ct); numeropresenze=np; numeroidentificativo=id; public void setnumeropresenze(int npr) numeropresenze=npr; public int getnumeropresenze() return numeropresenze; public void setnumeroidentificativo(int idf) numeroidentificativo=idf; public int getnumeroidentificativo() return numeroidentificativo;
Esercizio Creare un'applicazione Java che istanzi tre oggetti di tipo Stagista li memorizzi in un array e visualizzare lo stagista più giovane (sulla base dell anno di nascita maggiore).
Soluzione class UsaPersona public static void main(string[] args) int ind,app,max,i; Stagista primo=new Corsista("Rossi","Marzio","rssmrz80e65041u","Roma",56,23); Stagista secondo=new Corsista("Bianchi","Giovanni","bncgvn82e65042s","Roma",48,10); Stagista terzo=new Stagista ("Verdi","Bruno","vrdbrn76u56i578t","Roma",52,30); Stagista vett[]=primo,secondo,terzo;
max=integer.parseint(vett[0].annonascita()); ind=0; for (i=0;i<3;i++) app=integer.parseint(vett[i].annonascita()); if (max<app) max=app; ind=i; System.out.println( Lo stagista più giovane e':" +vett[ind].getcognome());
Esercizio Realizzare i metodi della classe Polinomio2G a partire dalla classe PolinomioG1 P( x ) = a 2 x 2 + a 1 x + a 0
Esercizio Arricchire il modello Polinomio2G introducendo dei metodi per il calcolo della soluzione e della somma di oggetti Polinomio2G.