Fondamenti di Informatica 1 - uniroma2.it · In Java si usa l’ereditarietà quando occorre...
-
Upload
nguyentuyen -
Category
Documents
-
view
217 -
download
2
Transcript of Fondamenti di Informatica 1 - uniroma2.it · In Java si usa l’ereditarietà quando occorre...
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