Fondamenti di Informatica 1 - uniroma2.it · In Java si usa l’ereditarietà quando occorre...

39
Fondamenti di Informatica 1 Prof. B.Buttarazzi A.A. 2010/2011

Transcript of Fondamenti di Informatica 1 - uniroma2.it · In Java si usa l’ereditarietà quando occorre...

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

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.

Si dice che la Sottoclasse estende la Superclasse.

• 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.

Esercizio

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;

}

. . .

}

Esempio class Persona

• 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.

Esercizio

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

incapsulamentoL’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.

class Persona {

protected String nome;

protected String cognome;

public Persona(String nome,String cognome){

this.nome=nome;

this.cognome=cognome;

}

public String getNome(){

return nome;

}

public String getCognome(){

return cognome;

}

}

Esempio class Persona

Nuovo tipo di

modificatore di

visibilità!

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.

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

Modificatori di accesso

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à

super fa riferimento all’istanza stessa come se appartenesse alla

superclasse

si usa per evitare ambiguità e per specializzare metodi

class Ciclista extends Persona {

Bicicletta bici;

boolean dimmiSeTua(Bicicletta

bici) {

return this.bici = bici;

}

}

class ContoCorrente {

float saldo;

void deposita(float somma) {

saldo += somma;

}

}

class ContoAziendale {

RegistroCassa registro;

void deposita(float somma) {

super.deposita(somma);

registro.annotaEntrata(somma);

}

}

PolimorfismoIn 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à.

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

Overriding:esempio Class Impiegato

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.

• 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.

Esercizio

• 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

• 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.

Esercizio

• 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;

Soluzione

• 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

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;

}

}

Soluzione

• Creare un'applicazione Java che istanzi un oggetto della

classe Persona e ne visualizzi in seguito nome, cognome ed

anno di nascita.

Esercizio

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);

}

}

• 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.

Esercizio

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;

}

}

Soluzione

• 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).

Esercizio

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};

Soluzione

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());

}

}

• Realizzare i metodi della classe Polinomio2G

a partire dalla classe PolinomioG1

P( x ) = a2

· x2 + a1

· x + a0

Esercizio

• Arricchire il modello Polinomio2G

introducendo dei metodi per il calcolo della

soluzione e della somma di oggetti

Polinomio2G.

Esercizio