LIP-07 - Esercitazione #13

Istruzioni

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 ACORSO BCORSO 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;

  • [82b]  Scrivere una classe concreta OraHM che realizza la classe astratta Ora utilizzando due variabili di istanza di tipo int per memorizzare rispettivamente i minuti e le ore, e con l'ovvio costruttore con due argomenti di tipo int (se i valori passati al costruttore non sono validi, allora assegnare 0 a entrambe le variabili).

    Aggiungere il metodo toString() per restituire una descrizione dell'ora nel formato "OraHM[hh:mm]".

  • [82c]  Scrivere una classe concreta OraSec che realizza la classe astratta Ora sfruttando una sola variabile di istanza di tipo int per memorizzare i secondi trascorsi nella giornata (da 0 a 86399, estremi inclusi). Fornire l'ovvio costruttore con un argomento di tipo int. Quale metodo della classe Ora conviene sovrascrivere?

    Aggiungere il metodo toString() per restituire una descrizione dell'ora nel formato "OraSec[hh:mm:ss]".

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