|
Università
di Padova
|
Diploma in Ingegneria Informatica
Corso di Fondamenti di Informatica 2
2 Moduli
|
A.A. 2001/2002
Versione 1.0 27/09/2001
Obiettivi ed esercizi di verifica
N.B. Le soluzioni in Java di alcuni degli esercizi di verifica
si trovano nel package FI2.Examples.
- Esercizi di verifica della settimana 1
- Obiettivi:
- Saper impostare in UML l'analisi di un programma
composto da più classi correlate
- Saper riconoscere ed utilizzare i costrutti principali
di Java (classe, costruttore, new, metodi, strutture di controllo)
- Saper utilizzare il JDK per la compilazione e collaudo
dei programmi
- Saper costruire piccole classi sulla base di semplici
specifiche, utilizzando accortamente il controllo di
visibilità dei membri
- Esercizi di verifica della settimana 2
- Obiettivi:
- Comprendere il significato di derivazione (ereditarietà)
con i concetti collegati di mascheramento, ridefinizione, astrazione
- Comprendere il significato delle diverse semantiche: isA, hasA,
useA, isPartOf, isRelatedTo (associazione)
- Saper sfruttare il ruolo delle interfacce
e il polimorfismo per applicare
un principio di generalizzazione
- Comprendere la funzione delle Eccezioni e la loro
gestione
Torna alla pagina principale
Esercizi settimana 1
Esercizio 1.1
Si progetti in UML un sistema di classi che descriva un anno di
corso del diploma. Il sistema deve includere le seguenti entità:
- Corso identificato dal nome, dal numero di moduli
e dal semestre
- Studente identificato da nome, cognome, numero
di matricola
- Docente identificato da nome, cognome
- DocenteLocale identificato da nome, cognome, centro
locale
- Lezione che associa una determinata data
ad una descrizione, presente in un apposito file,
del contenuto del seminario o incontro locale, e una specifica
se si tratta di seminario o incontro
- Valutazione che memorizza il voto assegnato
per un corso ad uno studente
Includere le relazioni che definiscono la frequenza di uno
studente, l'insegnamento dei docenti, ipotizzando che un
docente locale possa insegnare al massimo in due corsi,
il materiale da sviluppare negli incontri-seminari,
la valutazione degli studenti.
Studiare i tipi di dati più opportuni per
gli attributi.
Completare successivamente il progetto con alcuni metodi
pubblici ragionevoli per il dominio del problema.
Trasformare il diagramma per passare all'implementazione
Java e ricavare lo scheletro delle classi.
Esercizio 1.2
Realizzare una classe Bits che gestisce sequenze di 32
bit, singolarmente manipolabili, attraverso una rappresentazione
interna con un valore intero. A tale scopo si implementino i seguenti
metodi pubblici:
- Costruttore di default: una sequenza di bit tutti nulli.
- Costruttore con parametro stringa: la stringa rappresenta
in formato ASCII la sequenza di bit (solo caratteri 1 e 0;
gli zeri non significativi possono essere omessi; i caratteri
diversi sono semplicemente ignorati).
- Operatore and bitwise: esiste sia la versione
statica con due parametri di classe Bits che rappresentano
gli operandi, che quella d'istanza con un solo parametro di classe Bits
(l'altro operando è this).
- Operatore or bitwise: analogo ad and.
- Operatore not bitwise: analogo ad and
ma con un unico operando.
- Operatore bit: restituisce il valore booleano corrispondente
al bit di indice passato come parametro (0..31).
- equals: verifica l'eguaglianza (stessa sequenza rappresentata)
con un secondo Bits.
- toString: restituisce il valore rappresentato in
formato stringa.
- main: metodo di collaudo.
Esercizio 1.3
Definire una classe Square che memorizza quadrati
di numeri interi. Prevedere nella classe:
- Un costruttore di default che inizializzi il
valore a 0.
- Un costruttore con un parametro intero.
- Un costruttore con un parametro floating point.
- Un metodo query che restituisce, in un array
a 3 valori interi, il valore rappresentato e le sue radici
quadrate positiva e negativa.
- Un metodo statico check che verifica se un parametro
floating point rappresenta il quadrato di un valore intero
nel range (-1000..1000), ritornando un valore booleano.
- Un metodo set che imposta un nuovo valore.
- Un metodo toString di conversione a stringa.
- Un metodo main di collaudo.
Per la determinazione di una radice quadrata, si realizzi un metodo
locale root che calcola la radice applicando la proprietà
che i numeri interi che sono quadrati di un numero n sono ottenibili
come somma dei primi n numeri dispari. Se in fase di costruzione il valore
da assegnare è illegale, viene memorizzato il valore Integer.MIN_VALUE;
in fase di reimpostazione (metodo set) viene ritornato un errore.
Esercizio 1.4
Realizzare una classe Biglietto che rappresenta un biglietto
di autobus urbano a tariffa unica. La classe include:
- Una costante pubblica prezzo che rappresenta la tariffa.
- Un campo statico venduti che totalizza il numero di biglietti venduti
a qualsiasi tariffa e, perciò, il numero da assegnare al prossimo biglietto venduto.
- Un campo statico ridotti che totalizza il numero di biglietti
a tariffa ridotta.
- Un campo statico obliterati che totalizza il numero di biglietti obliterati.
- Un campo numero che memorizza il numero d'ordine del biglietto.
- Un campo nuovo che rappresenta lo stato di non obliterato.
- Un costruttore di default che corrisponde all'acquisto di un biglietto a tariffa
piena.
- Un costruttore alternativo che corrisponde all'acquisto di un biglietto a tariffa
ridotta del 10%.
- Un metodo pubblico oblitera che ritorna false se il biglietto è
già obliterato, cambia stato al biglietto e ritorna true altrimenti.
- Un metodo toString che fornisce in formato stringa il numero e
lo stato del biglietto.
- Un metodo statico totali che fornisce in formato stringa il
numero di biglietti venduti, gli obliterati, i ridotti, e il totale incassato.
- Un metodo main di collaudo.
L'inizializzazione dei membri statici deve avvenire in un blocco statico.
Definire successivamente la classe Carnet le cui istanze corrispondono
ad un carnet di 10 biglietti venduti ad un prezzo scontato del 10%.
Il carnet è memorizzato in un array interno alla classe. Definire
i seguenti metodi:
- Un costruttore di default.
- Un metodo pubblico oblitera che ritorna false se tutto il carnet
è usato, oblitera il prossimo biglietto e ritorna true altrimenti.
- Un metodo toString che fornisce in formato stringa il numero iniziale
e finale del carnet e il numero di biglietti non obliterati.
- Un metodo statico totali che fornisce in formato stringa il
numero di carnet venduti e il totale incassato con i carnet.
- Un metodo main di collaudo.
Torna all'indice
Esercizi settimana 2
Esercizio 2.1
Si realizzi la classe Cruci che rappresenta un cruciverba. La classe
ha un costruttore che riceve i parametri n numero delle righe,
m numero delle colonne, e un array di coppie di coordinate
che rappresenta l'insieme delle caselle nere. Una coppia è rappresentata
da un oggetto di classe Coppia, opportunamente definita.
Cruci fornisce i seguenti servizi:
- Interrogazione: vengono forniti come parametri
una coppia e una direzione (orizzontale o verticale).
Controlla che la casella esista e sia all'inizio di una definizione
del cruciverba (ovvero in una posizione che su un
cruciverba normale farebbe sì che alla casella
fosse assegnato un numero). Restituisce la stringa attuale
contenuta nella riga o colonna richiesta, con caratteri ?
al posto degli spazi; restituisce null in
caso di parametri errati.
- Verifica: stessi parametri della precedente. Ritorna true
se corrisponde ad una definizione completa, false se parziale
(con spazi). Solleva una eccezione se i parametri sono errati.
- Inserimento: vengono forniti come parametri
una coppia e un carattere. Se la coppia corrisponde
ad una casella vuota, questa viene riempita con il carattere
fornito, se piena, il carattere fornito sostituisce quello
attuale. Viene sollevata una eccezione se la posizione è
errata.
- Conversione a stringa (metodo toString): visualizza
su STDOUT tutto il cruciverba, indicando con * le
caselle nere.
Esercizio 2.2
Si modifichi la classe Bits dell'esercizio 1.2 nella
classe EBits in modo da renderla estendibile, e la si
estenda con la classe SBits avente le seguenti caratteristiche:
- Aggiunge un campo che rappresenta
un verso di shifting e che può assumere uno dei
due valori LEFT, RIGHT, definiti in SBits
come costanti locali.
- Ha 2 costruttori analoghi a quelli di EBits che
assegnano il verso di shifting a LEFT, e un quarto
costruttore che ha due parametri, un parametro stringa e
un booleano: la stringa rappresenta la sequenza di bit
e il booleano è true se il verso dev'essere
LEFT, false se RIGHT.
- La classe è clonabile e per questo implementa
l'interfaccia Cloneable.
- Ridefinisce il metodo d'istanza or utilizzando i metodi
ereditati and e not e la legge di De Morgan:
x or y == not(not x and not y).
- Ridefinisce il metodo toString aggiungendo alla
stringa restituita dal metodo ereditato omologo l'indicazione
del verso di shifting.
- Aggiunge il metodo shift con parametro naturale n
che effettua l'operazione di shift logico della
sequenza corrente nel verso corrente in un numero di
passi pari a [n modulo 32] (0..31).
- Aggiunge il metodo rot con parametro naturale n che,
utilizzando i metodi ereditati, effettua sul valore corrente
una rotazione circolare nel verso corrente in numero di passi
pari a [n modulo 32] (0..31).
- Aggiunge un nuovo metodo di collaudo per la parte
non ereditata.
Esercizio 2.3
Si definisca l'interfaccia SuFigura che rappresenta
le azioni comuni su una figura geometrica, e precisamente i metodi:
- move: trasla la figura di un vettore fornito, rappresentato
da un oggetto di classe PointE
- rotate: ruota la figura di un angolo fornito attorno al centro
- zoom: riduce o aumenta le dimensioni della figura
secondo un fattore fornito (< 1 se riduzione, > 1 se ingrandimento)
- show: visualizza la figura
Si definisca quindi una classe astratta Figura che
implementa in parte SuFigura e che memorizza
la posizione del centro della figura (oggetto di classe PointE)
e realizza il solo metodo move.
Dalla classe Figura si derivino le classi Poligono
e Cerchio. La classe Poligono
memorizza il numero dei lati e i vertici,
questi ultimi in un array di oggetti di classe PointE che esprimono
le componenti cartesiane dei vettori che collegano il centro del poligono
(un punto interno, mediano di una diagonale;
si assuma il poligono convesso) e i vertici stessi;
implementa inoltre tutti i metodi
non ereditati (una versione semplificata show stampa
su STDOUT le posizioni del centro e dei vertici)
e il metodo perim che calcola il perimetro.
La classe Cerchio memorizza il raggio del
cerchio (il centro coincide con il centro geometrico) e implementa
i metodi non ereditati (si noti che rot è in
questo caso un'operazione nulla; una versione semplificata
show stampa su STDOUT le posizioni del
centro e il raggio) e i metodi perim che calcola
il perimetro e area che calcola l'area.
Dalla classe Poligono si derivino le classi Rettangolo
e Triangolo. La classe Rettangolo ridefinisce il metodo
perim per tener conto dell'eguale lunghezza di due lati opposti,
e implementa il metodo area. La classe Triangolo definisce
il metodo area applicando la formula di Erone (area=sqrt(p*(p-a)*(p-b)*(p-c))
p semiperimetro).
Dalla classe Rettangolo si derivi la classe Quadrato
che ridefinisce sia il metodo perim che area per
tener conto della eguaglianza dei lati.
Esercizio 2.4
Si consideri la seguente interfaccia:
public interface FormattedOutput
{
public String out(String format);
}
Il metodo out restituisce in una stringa una rappresentazione
formattata del valore (principale) contenuto nell'oggetto che
implementa l'interfaccia. La stringa format descrive
le modalità di composizione
della stringa di output secondo una convenzione
derivata da quella utilizzata dalla funzione printf
del linguaggio C e precisamente:
simbolo | opzionale | significato |
- | si | allineamento a sinistra |
numero | si | minimo numero di caratteri che forma
la stringa di output: se i caratteri significativi sono meno,
vengono aggiunti spazi a destra o a sinistra a seconda dell'allineamento |
. [punto] | si | separa il numero precedente dal seguente |
numero | si | nel caso di una stringa, è
il massimo numero di caratteri da rappresentare in output; nel caso di
un numero, la precisione (numero massimo di cifre per un intero,
numero di decimali per un floating point)
|
carattere di conversione | no |
d intero decimale
o intero ottale: la stringa di output ha uno 0 iniziale obbligatorio
x intero esadecimale: la stringa di output ha un prefisso 0x obbligatorio
c singolo carattere
s stringa: o l'intera stringa oggetto oppure un suo
prefisso lungo quanto la precisione, se specificata
f float rappresentato come [-]mmm.nnnn ove i decimali sono in numero pari
alla precisione (6 se non indicata); per i complessi il formato è valido
per ciascuna delle due componenenti ovvero [-]mmm.nnnn±mmm.nnnnj
e floating rappresentato come [-]m.nnnnnne[±]xx (decimali come sopra)
|
Tenendo presente che le classi wrapper di Java non sono
estendibili, definire, con i metodi strettamente necessari, le seguenti
classi wrapper che implementano l'interfaccia FormattedOutput:
- FInt
per i numeri interi: accetta le specifiche di formato d,
o, x, f, e.
- FDouble
per i numeri floating point: accetta le specifiche di formato
d, o, x (per queste 3 visualizza solo la parte intera),
f, e.
- FComplex
, che estende FI2.Examples.DVect per i numeri complessi: accetta
le stesse specifiche di FDouble applicandole a ciascuna delle sue componenti.
- FStr
, per stringa: accetta le specifiche di formato s e c,
per questa seconda visualizzando il primo carattere
- FChar
, per singolo carattere: accetta le specifiche di formato c e s
(stesso effetto)
In ciascuna classe il metodo out deve sollevare un'eccezione se la stringa
di formato è illegale.
Definire infine infine la classe Format che implementa il metodo statico:
public static String out(String formatStr, FormattedOutput[] values);
che riceve nel parametro formatStr una stringa contenente
sequenze di caratteri normali (compresi spazi) alternate a stringhe
di formato precedute dal carattere speciale % (il carattere
normale % viene rappresentato con %%). Ad esempio:
Il valore calcolato è: %3.5d (float=%e)
Nel parametro values il metodo riceve un array di
oggetti FormattedOutput (cioè che implementano
quell'interfaccia). Il metodo restituisce una stringa
che è ricavata dalla stringa formatStr
sostituendo nell'ordine ad ogni sottostringa di formato la
stringa formattata prodotta dal metodo out applicato
ai successivi oggetti dell'array values.
Valutare cosa fare nel caso non vi sia una corrispondenza
in numero tra sottostringhe di formato e oggetti nell'array
(più strighe e meno oggetti, o viceversa).
La classe Format contiene anche un metodo main
di collaudo.
Torna all'indice
Torna alla pagina principale