Questa esercitazione verte principalmente
sui concetti basici dell'ereditarietà, classi astratte e interfacce.
Come sempre, prima della fine dell'esercitazione siete invitati a
inviare tutti i file .java
prodotti (anche se incompleti) al docente come attachment di un
unico messaggio di posta elettronica con Subject: LIP-07 Es13.
Indirizzi di posta
elettronica da
utilizzare per inviare programmi svolti in aula o a casa dopo le
esercitazioni.
CORSO A | CORSO B | CORSO C |
lipa-doc oppure lipa-doc@cli.di.unipi.it
|
lipb-doc oppure lipb-doc@cli.di.unipi.it
|
lipc-doc oppure lipc-doc@cli.di.unipi.it
|
Esercizi
Si suggerisce di creare un nuovo progetto Eclipse per i file di questa esercitazione,
chiamandolo ad esempio LIP-ES-13.
Per gli esercizi che coinvolgono array, usare i metodi
della classe ArrayUtils.java quando opportuno.
Per leggere dei dati in
input da tastiera, usare la classe Input.java. Ricordarsi di
importare entrambe le classi nel package.
|
- [79]
Sia data l'interfaccia
Figura
così definita:
public interface Figura {
// restituisce l'area della figura
double area();
} |
Scrivere la classe astratta FiguraComp che implementa sia
l'interfaccia Figura che Comparable. La classe
FiguraComp deve contentere
- due variabili d'istanza dim1 e dim2, di tipo double e dichiarate protected;
- un costruttore con due parametri double, che inizializza le variabili
d'istanza nel modo ovvio;
- il metodo public int
compareTo(Object o) che realizza il metodo
astratto dell'interfaccia Comparable, confrontando
due oggetti di tipo FiguraComp in
base all'area: un oggetto precede un altro se ha area minore;
- il metodo
equals, definito in modo consistente
con compareTo, come visto a lezione:
It is strongly recommended... that (x.compareTo(y)==0) == (x.equals(y)).
Si noti che la classe FiguraComp
deve essere astratta, perchè non fornisce un'implementazione
del metodo dell'interfaccia Figura.
Scrivere quindi le classi concrete Rettangolo e Triangolo
che estendono FiguraComp e la classe Quadrato che estende Rettangolo. Ricordarsi di definire opportunamente anche il metodo toString().
Per testare le classi, usare la classe
TestFigure.java,
modificandola a piacere. Verificare in particolare che con questa
organizzazione delle classi è possibile confrontare oggetti
di classi diverse (Triangolo e
Rettangolo) con compareTo e con equals poiché questi metodi sono definiti
in una superclasse (astratta) comune.
- [80] La classe java.util.Arrays
(documentazione)
fornisce alcuni metodi statici di utilità generale
per manipolare array. Ad esempio, fornisce il metodo void sort(Object [] a)
che, assumendo che tutti gli oggetti dell'array implementino
l'interfaccia Comparable ordina
l'array passato per argomento in modo crescente.
Verificare quanto affermato con una classe TestArraysSort che:
- crea
un array di stringhe, e ne stampa il contenuto prima e dopo
averci invocato il metodo Arrays.sort;
- crea
un array di figure (vedi esercizio [79]), e ne stampa il contenuto prima e dopo
averci invocato il metodo Arrays.sort.
Nota: ricordarsi di importare java.util.Arrays.
- [81] Il metodo toString() convenzionalmente
restituisce una rappresentazione testuale dell'oggetto su cui
viene invocato, cioè una stringa contenente il nome della
classe seguito dalla lista dei valori delle variabili d'istanza.
Rispettare tale convenzione può diventare complicato in
presenza di classi con variabili private che vengono estese da sottoclassi.
Definire il metodo toString() nelle classi Cittadino e Contribuente in modo che
rispetti la convenzione descritta sopra.
public class Cittadino {
private String nome;
public Cittadino(String n) { nome = n; }
} |
public class Contribuente extends Cittadino {
private double reddito;
public Contribuente(String n, double r) {
super(n);
reddito = r;
}
} |
Attenzione:
Alle classi Cittadino e Contribuente va aggiunto
solo il metodo toString(): nessun altro metodo o variabile.
Eseguire il programma Test81,
e correggere i metodi toString() finché l'output
non sia il più possibile simile a quello riportato sotto.
java Test81
Cittadino[nome=Gino Scafroglia]
Contribuente[nome=Ciro De Napoli][reddito=30000.0]
|
Suggerimento: Il nome della classe più specifica di un oggetto obj si ottiene con
l'espressione obj.getClass().getName()
-
[82a] Scrivere una classe astratta Ora, che implementa l'interfaccia Comparable, per rappresentare
gli orari di una giornata, con i soli membri:
- public abstract int getHH()
che restituisce l'ora (da 0 a 23);
- public abstract int getMM()
che restituisce i minuti (da 0 a 59);
- public int compareTo(Object
o)
che restituisce la differenza in minuti tra l'ora
this e l'ora o ricevuta come parametro;
- public boolean equals(Object
obj)
che restituisce true solo se gli orari
coincidono;
-
[82d] Scrivere un programma TestOra che:
- memorizza nelle variabili o1 e o2 di tipo
Ora due oggetti,
uno per ciascuna realizzazione,
creati con valori delle variabili d'istanza letti da tastiera;
- sperimenta i metodi disponibili nell'interfaccia;
- stampa gli orari.
-
[83] Scrivete una gerarchia
di ereditarietà per figure geometriche. La gerarchia dovrebbe comprendere le sottoclassi concrete Sfera,
Parallelepipedo,
Cubo,
Cilindro,
Rettangolo,
Quadrato,
Cerchio fattorizzandone le caratteristiche comuni in opportune superclassi
astratte e interfacce, tra le quali si considerino almeno Shape, Shape2D
e Shape3D (figure bidimensionali e tridimensionali).
Nota: Dichiarare come PRIVATE tutte le variabili d'istanza.
Corredate le classi di opportuni costruttori in modo da garantire che
i valori delle varie dimensioni non siano negativi.
Inserite opportunamente il metodo toString() nelle classi (astratte e
concrete) per stampare il tipo e le caratteristiche di ogni forma
della gerarchia. Considerate anche i metodi perimetro,
volume,
peso, superficeTotale e area: decidete in
quale classe astratta vanno inseriti, e come devono essere
implementati nelle classi della gerarchia.
Scrivete infine un programma per collaudare la gerarchia Shape
e i suoi metodi.
- [84] Si considerino le seguenti specifiche:
-
Un elemento multimediale è una immagine, un filmato o una registrazione audio identificato da un titolo (una stringa non vuota).
-
Un elemento è riproducibile se ha una durata (un valore positivo di tipo int) e un metodo play()
-
Una registrazione audio è riproducibile e ha associato anche un volume (un valore positivo di tipo int) e i metodi weaker() e louder() per regolarlo. Se riprodotta, ripete per un numero di volte pari alla durata la stampa del titolo concatenato a una sequenza di punti esclamativi di lunghezza pari al volume (una stampa per riga).
-
Un filmato è riproducibile e ha associato un volume regolabile analogo a quello delle registrazioni audio e anche una luminosità (un valore positivo di tipo int) e i metodi brighter() e darker() per regolarla. Se riprodotta, ripete per un numero di volte pari alla durata la stampa del titolo concatenato a una sequenza di punti esclamativi di lunghezza pari al volume e poi a una sequenza di asterischi di lunghezza pari alla luminosità (una stampa per riga).
-
Un'immagine non è riproducibile, ma ha una luminosità regolabile analoga a quella dei filmati e un metodo show() che stampa il titolo concatenato a una sequenza di asterischi di lunghezza pari alla luminosità
-
Eseguire un oggetto multimediale significa invocarne il metodo show() se è un'immagine o il metodo play() se è riproducibile.
Organizzare opportunamente con classi astratte, interfacce e classi concrete il codice di un lettore multimediale che memorizza 5 elementi (creati con valori letti da tastiera) in un array e poi chiede ripetutamente all'utente quale oggetto eseguire (leggendo un intero da 1 a 5 oppure 0 per finire) e dopo ogni esecuzione fornisce la possibilità di regolarne eventuali parametri (volume / luminosità).
|