LIP-06 - Esercitazione #10

Istruzioni

Questa esercitazione verte principalmente sulla realizzazione di classi.

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 Es10 (ad esempio usando pine, seguendo le corrispondenti istruzioni).

Indirizzi di posta elettronica da utilizzare per inviare programmi svolti in aula o a casa dopo le esercitazioni.

CORSO ACORSO B
lipa-doc oppure lipa-doc@cli.di.unipi.it lipb-doc oppure lipb-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-10. Se hai problemi con Eclipse, prova a guardare la breve introduzione all'uso di eclipse o segui le istruzioni riassuntive sui primi passi con Eclipse.
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.

  • [62]  Scrivere un programma LeggiMultipli che legge una sequenza di valori positivi, assicurandosi che ognuno sia un multiplo del valore precedente. Infatti, la lettura termina quando l'ultimo valore immesso non è divisibile per il precedente. Eventuali valori negativi e lo zero sono semplicemente ignorati. Alla fine bisogna stampare il quoziente tra l'ultimo multiplo immesso e il primo valore (positivo) della sequenza.

    Attenzione: il programma NON DEVE utilizzare alcun array.

Esempio di interazione con il programma (in blu l'input dell'utente):
Dammi il primo valore (>0): -5
Dammi il primo valore (>0): 2
Dammi un multiplo di 2 (>0): 4
Dammi un multiplo di 4 (>0): 32
Dammi un multiplo di 32 (>0): 64
Dammi un multiplo di 64 (>0): 80
64 diviso 2 = 32


  • [63] Importare nel progetto la classe BankAccount vista a lezione e modificarne il codice in modo che:

    • ci sia una variabile di istanza per il nome del proprietario del conto (ricordarsi di modificare anche i costruttori per inizializzare questa variabile);

    • i costruttori garantiscano che il saldo iniziale non sia negativo;

    • il metodo deposit invece di essere dichiarato come void restituisca un risultato di tipo boolean: in particolare, deve restituire false senza modificare il saldo se il valore passato per argomento è negativo, mentre deve restituire true aggiornando il saldo in caso contrario;

    • se l'argomento passato al metodo withdraw è negativo il saldo rimanga invariato, e se l'argomento passato al metodo withdraw è superiore al saldo venga prelevato un importo pari al saldo; inoltre fare in modo che invece di essere dichiarato come void, il metodo withdraw restituisca un double pari all'importo prelevato;

    • ci sia un metodo public boolean transfer(BankAccount another, double amount) per trasferire l'importo amount sul conto another facendo opportuni controlli di consistenza (importo positivo e disponibile sul conto), e restituendo true o false a seconda che il trasferimento vada a buon fine oppure no.

    • ci sia un metodo getInfo che restituisca i dati del proprietario del conto.

    Scrivere poi una classe TestBankAccount che

    1. crea due oggetti di tipo BankAccount con proprietari e saldi iniziali letti da tastiera (assicurando la validità dei dati);

    2. con un ciclo legge da tastiera una sequenza di importi da trasferire dal primo conto al secondo e stampa ogni volta l'esito dell'operazione e la situazione dei conti; si esce dal ciclo quando il saldo del primo conto è 0;

Esempio di interazione con il programma (in blu l'input dell'utente)
Nome (stringa non vuota): Bob
Saldo iniziale di Bob (valore positivo): 2105
Nome (stringa non vuota):
Nome (stringa non vuota): Alice
Saldo iniziale di Alice (valore positivo): -34
Saldo iniziale di Alice (valore positivo): 65
Quanto vuoi trasferire? 27
Il trasferimento ha avuto successo.
Il saldo di Bob e' 2078.0
Il saldo di Alice e' 92.0
Quanto vuoi trasferire? 583
Il trasferimento ha avuto successo.
Il saldo di Bob e' 1495.0
Il saldo di Alice e' 675.0
Quanto vuoi trasferire? 1295
Il trasferimento ha avuto successo.
Il saldo di Bob e' 200.0
Il saldo di Alice e' 1970.0
Quanto vuoi trasferire? 205
Il trasferimento non ha avuto successo.
Il saldo di Bob e' 200.0
Il saldo di Alice e' 1970.0
Quanto vuoi trasferire? 200
Il trasferimento ha avuto successo.
Il saldo di Bob e' 0.0
Il saldo di Alice e' 2170.0


  • [64] Scrivere la classe Buffer i cui oggetti rappresentano dei buffer a una posizione. Un buffer può essere vuoto oppure contenere un messaggio di tipo String. Un buffer mette a disposizione tre operazioni principali: isEmpty() permette di controllare se il buffer è vuoto oppure no; put(s) permette di inserire la stringa s in un buffer, ma solo se il buffer è vuoto; get() permette di estrarre la stringa contenuta nel buffer, ma solo se il buffer non è vuoto. La classe deve contenere:

    • Le variabili d'istanza e i costruttori ritenuti opportuni.

    • I metodi d'istanza necessari a implementare le tre funzionalità descritte sopra, badando di gestire eventuali usi scorretti del buffer come l'invocazione di get() su un buffer vuoto con la stampa a video di un messaggio di errore e/o la restituzione di un valore particolare (es. null).

      Nota: vedremo più avanti nel corso che il meccanismo adeguato per gestire le situazioni anomale in Java è quello delle cosiddette eccezioni.

    Per testare la classe, scrivere un programma TestBuffer che crea un oggetto della classe Buffer e in maniera iterativa offre all'utente la possibilità di invocare una delle tre funzionalità sul buffer (visualizzando l'esito dell'operazione) o di terminare l'esecuzione.


  • [65] La classe java.awt.Point definisce degli oggetti che rappresentano dei punti in uno spazio bidimensionale, aventi come variabili di istanza le coordinate x e y di tipo int. Si consulti la documentazione della classe, accedendovi tramite Eclipse oppure cliccando su questo link, per vedere quali metodi fornisce.

    In questo esercizio vogliamo definire una classe chiamata Punto che si ispira alla classe java.awt.Point. Scrivere quindi la classe Punto che contiene:

    • due variabili di istanza private x e y di tipo int;

    • un costruttore senza argomenti che crea un punto di coordinate (0,0);

    • un costruttore con due argomenti di tipo int che inizializza le variabili di istanza con i valori passati per argomento;

    • due metodi pubblici: getX che restituisce l'ascissa del punto e getY che restituisce l'ordinata;

    • un metodo pubblico translate con due parametri di tipo int, che trasla il punto aggiungendo alle coordinate i valori passati per argomento;

    • un metodo pubblico distance di tipo double e con un solo parametro di tipo Punto, che restituisce la distanza tra l'oggetto su cui viene invocato e il punto passato per argomento, calcolata usando il Teorema di Pitagora, cioè
      RadiceQuadrata(Quadrato(differenza delle ascisse) + Quadrato(differenza delle ordinate)).
      Per il calcolo della radice quadrata, usare il metodo fornito dalla classe Math.

    • un metodo pubblico toString senza argomenti, che restituisce una stringa che è una rappresentazione testuale del punto, ad esempio "(vx, vy)", dove vx è l'ascissa del punto e vy è l'ordinata.

    Scrivere poi una classe TestPunto che

    1. chiede all'utente se vuole inserire le coordinate del punto oppure no;

      • se l'utente risponde negativamente, crea un punto con il costruttore senza parametri;

      • se l'utente risponde positivamente, chiede i valori delle coordinate e poi crea un punto con i valori forniti dall'utente;

    2. stampa la rappresentazione testuale del punto, con un opportuno commento;

    3. trasla il punto di 5 unità lungo le ascisse e di 10 unità lungo le ordinate;

    4. stampa nuovamente la rappresentazione testuale del punto, con un opportuno commento;

    5. stampa la distanza del punto dall'origine degli assi, cioè dal punto di coordinate (0, 0).
Esempi di interazione con il programma (in blu l'input dell'utente)
Vuoi darmi le coordinate del punto? (s/n) n
Il punto creato e': (0 , 0)
Il punto spostato e': (5 , 10)
La distanza dall'origine e': 11.180339887498949
Vuoi darmi le coordinate del punto? (s/n) s
Dammi il valore dell'ascissa: 7
Dammi il valore dell'ordinata: 2
Il punto creato e': (7 , 2)
Il punto spostato e': (12 , 12)
La distanza dall'origine e': 16.97056274847714


  • [66] Scrivere la classe Bulb i cui oggetti rappresentano delle lampadine elettriche. Una lampadina può essere accesa, spenta o rotta, e mette a disposizione due sole operazioni: look() che restituisce lo stato corrente della lamadina e click() che ne cambia lo stato da accesa a spenta o da spenta a accesa. Una lampadina si rompe dopo un certo numero di click deciso dal fabbricante. La classe deve contenere:

    • Le variabili d'istanza e i costruttori ritenuti opportuni.

    • I metodi d'istanza necessari a implementare le funzionalità descritte sopra.

    Per testare la classe, scrivere un programma TestBulb che crea un oggetto della classe Bulb che ammetta un numero massimo di click deciso dall'utente e poi, in maniera iterativa, offre all'utente la possibilità di invocare una delle due funzionalità (visualizzando l'esito dell'operazione) o di terminare l'esecuzione.


  • [67] Scrivere la classe Switch i cui oggetti rappresentano degli interruttori. Ogni interruttore è collegato a una lampadina e ne regola l'accensione e spegimento. La classe deve contenere tutte le variabili d'istanza i costruttori e i metodi ritenuti opportuni.

    Per testare la classe, scrivere un programma TestSwitch che crea due interruttori (oggetti della classe Switch) entrambi collegati alla stessa lampadina (oggetto della classe Bulb) e poi, in maniera iterativa, offre all'utente la possibilità di agire su uno dei due interruttori (visualizzando l'esito dell'operazione) o di terminare l'esecuzione.


  • [68] Scrivere la classe Segmento i cui oggetti rappresentano dei segmenti orizzontali di lunghezza intera sul piano cartesiano. In figura sono mostrati due segmenti, rispettivamente con vertice (2,3) e lunghezza 3 e con vertice (1,1) e lunghezza 2.
    La classe deve contenere:

    • variabile d'istanza e costruttori opportuni

    • un costruttore con due parametri formali Punto left e int length, che crea un segmento con vertice sinistro left e lunghezza length se maggiore di zero, e lunghezza 1 altrimenti;

    • un costruttore con un parametro formale di tipo int, che crea un segmento con vertice destro (0,0) e lunghezza uguale al parametro se maggiore di zero, e uguale a 1 altrimenti;

    • un costruttore con due parametri formali left e right di tipo Punto, che rappresentano i vertici sinistro e destro del segmento se allineati, altrimenti con vertice sinistro left e lunghezza 1;

    • un metodo getLeft(), che restituisce il vertice sinistro del segmento;

    • un metodo getRight(), che restituisce il vertice destro del segmento;

    • un metodo getLength(), che restituisce la lunghezza del segmento;

    • un metodo toString senza argomenti, che restituisce una stringa che è una rappresentazione testuale del segmento, ad esempio "Segmento[(xleft, yleft),length]", dove xleft è l'ascissa del vertice sinistro, yleft è l'ordinata del vertice sinistro e length è la lunghezza.

    • un metodo booleano inclusoIn con un singolo parametro di tipo Segmento, che restituisce true se e solo il segmento su cui il metodo viene invocato è contenuto nel segmento passato come parametro.

    • un metodo booleano interseca con un singolo parametro di tipo Segmento, che restituisce true se e solo se i due segmenti si intersecano;

    Per testare la classe, scrivere un programma TestSegmento che sperimenta tutti i metodi della classe.