[AEKI]
Definire una piccola gerarchia di classi per gestire il catalogo di una
azienda che vende mobili (componibili) e combinazioni di mobili, secondo
le indicazioni seguenti.
- (max 13 punti)
-
Definire una classe base
Articolo
che gestisce i dati comuni: il codice (una stringa), non modificabile,
e la dimensione (larghezza, altezza e profondità in cm) rappresentata tramite
una classe nidificata statica Misura
le cui istanze sono immutabili. La classe Misura
ridefinisce
toString()
di Object
. Il costruttore di Articolo
ha due argomenti: il codice e la dimensione. La classe Articolo
ha dei metodi
per leggere il codice e la dimensione. Ha un metodo float getPrezzo()
che
sarà ridefinito dalle sottoclassi e ritorna 0. Inoltre, ridefinisce
il metodo equals()
di Object
: due oggetti Articolo
sono uguali se hanno lo stesso codice.
-
Definire una sottoclasse
Mobile
per gestire i dati di un mobile:
la categoria (una stringa, ad es. "Libreria", "Vetrina", ecc.) non modificabile,
il prezzo (un float
) e la gamma dei colori (un elenco di stringhe).
Il costruttore prende in input anche la categoria e il prezzo. La classe Mobile
ha un metodo per leggere la categoria, un metodo per impostare il prezzo e ridefinisce
getPrezzo()
. Ha un metodo
boolean addColore(String c)
che aggiunge il colore c
solo se non è
già presente (se lo aggiunge ritorna true
, altrimenti false
),
se c
è null
lancia NullPointerException
.
Ridefinisce il metodo toString()
ed ha un metodo che
ritorna la gamma dei colori, in un array creato ex novo.
-
Definire una sottoclasse
Comb
di Articolo
per gestire
i dati di una combinazione di mobili: la percentuale di sconto (un intero compreso tra 0 e 100)
e l'elenco dei mobili (di tipo Mobile
) componenti.
Il costruttore non prende in input altri dati oltre quelli della superclasse.
La classe ha un metodo per impostare lo sconto; se l'intero in input non
è compreso tra 0 e 100, lancia IllegalArgumentException
.
Ridefinisce getPrezzo()
così che ritorni
la somma dei prezzi dei mobili componenti scontata dello sconto.
Ha un metodo void addMobile(Mobile m)
che aggiunge
un mobile componente (una combinazione può avere due o più
componenti uguali) e se m
è null
, lancia
NullPointerException
. Ridefinisce toString()
ed ha
un metodo int contains(Mobile m)
che ritorna quante volte il mobile m
è nella combinazione.
Ecco un esempio di cosa devono ritornare i metodi toString()
di Mobile
e Comb
(nell'esempio, una vetrina di codice 123.400
, una libreria di codice
123.407
e una combinazione di codice 208.609
composta da
2 mobili di codice 123.400
e un mobile di codice 123.407
):
"Vetrina 123.400 L: 40cm, H: 170cm, P: 60cm
Colori: Bianco Beige Marrone
Prezzo: 120.0"
"Libreria 123.407 L: 60cm, H: 120cm, P: 60cm
Colori: Marrone
Prezzo: 90.0"
"Combinazione 208.609 L: 140cm, H: 170cm, P: 60cm
2 Vetrina 123.400 L: 40cm, H: 170cm, P: 60cm
1 Libreria 123.407 L: 60cm, H: 120cm, P: 60cm
Prezzo: 297.0"
Si osservi che nel caso di una combinazione, se è composta da due o più
componenti uguali, i dati di questi vanno accorpati e va riportata la loro quantità.
La combinazione ha uno sconto del 10%;
- (max 5 punti) Aggiungere alla classe
Articolo
un metodo statico
Comb[] trova(Articolo[] art, Mobile m, float max)
che ritorna in un array le combinazioni nell'array art
che hanno
come componente il mobile m
e il cui prezzo
non supera max
.
[Errori] (
max 4 punti)
Il seguente codice Java contiene uno o più errori. Trovare gli errori,
spiegarli e dire per ognuno se si verifica in compilazione o
in esecuzione.
public class Esame {
public static void main(String[] args) {
String[] sA = new String[10];
String[][] sM = new String[5][];
sM[0] = sA;
int n = sA[0].length();
System.out.println(sM.toString());
Object[] oA = new int[6][6];
n = oA[0][0];
oA[0] = new long[5];
sM[0][0] = "prova";
System.out.println(sA[0].length());
Object o = new String[] {"A", "B"};
System.out.print(o.length());
((int[])oA[1])[2] = 13;
}
}
[GeoMap]
Si vuole definire una classe
GeoMap
per rappresentare mappe geografiche (semplificate).
Una mappa geografica è una matrice rettangolare
M
i cui elementi sono entità geografiche.
Una entità geografica è univocamente determinata da un codice (un numero intero positivo), ha
un tipo (una stringa che può assumere i valori
"LAKE"
,
"RIVER"
,
"CITY"
, ecc.) e un nome
(una stringa, ad esempio "Roma", "Garda", ecc.).
Se
M[i][j]
contiene, ad esempio, il riferimento ad una entità
{1002, "CITY", "Roma"}
significa che l'entità geografica
"Roma"
occupa la posizione
(i, j)
.
Una stessa entità geografica può occupare più posizioni.
- (max 6 punti)
Definire la classe
GeoMap
con una classe nidificata statica Entity
che
rappresenta entità geografiche. La classe Entity
ridefinisce equals
di Object
e le sue istanze sono immutabili. Il costruttore di GeoMap
ha due parametri interi nr
e nc
e costruisce una mappa di
dimensione nr×nc
i cui elementi sono inizializzati a null
.
Definire un metodo void set(int r, int c, Entity g)
che inserisce l'entità
g
nella posizione (r, c)
della mappa e se (r, c)
non è una posizione della mappa, lancia IllegalArgumentException
.
GeoMap
ha un metodo void print(int r, int c, int n)
che stampa a video
un quadrato di n×n
caratteri relativo alla sottomappa
che inizia nella posizione (r, c)
ed ha n
righe e n
colonne. Per ogni posizione della sottomappa, se c'è una entità stampa
il carattere iniziale del nome, altrimenti stampa il carattere '.'
(si veda
l'esempio più avanti).
- (max 6 punti)
Aggiungere alla classe
GeoMap
un metodo public int count(String t)
che ritorna il numero di entità distinte di tipo t
presenti nella mappa
(si veda l'esempio più avanti).
- (max 6 punti)
Aggiungere un altro costruttore che prende come argomento il pathname di un file e
costruisce una mappa con le entità geografiche specificate nel file. Il
file ha il seguente formato. La prima linea contiene due interi
nr
e
nc
separati da uno spazio che specificano le dimensioni della mappa.
le linee successive hanno il formato: C T N r c
. Dove C T N
sono,
nell'ordine, il codice, il tipo e il nome di una entità geografica e r c
specificano una posizione occupata dall'entità. Tutte le posizioni non
specificate sono inizializzate a null
. Per semplicità, si può
assumere che il tipo e il nome non contengano spazi.
Un esempio di file è il seguente:
100 200
1002 CITY Roma 50 15
1012 RIVER Tevere 48 13
1012 RIVER Tevere 49 14
1002 CITY Roma 51 15
1002 CITY Roma 50 16
1050 LAKE Albano 47 18
1050 LAKE Albano 46 18
1002 CITY Roma 51 16
1060 LAKE Nemi 46 15
Se
map
è la mappa creata tramite il file d'esempio,
l'invocazione
map.print(46, 12, 7)
stampa:
...N..A
......A
.T.....
..T....
...RR..
...RR..
.......
le invocazioni
map.count("LAKE")
e
map.count("CITY")
ritornano, rispettivamente,
2
e
1
.