Laboratorio di programmazione in Java 8850321457, 9788850321452

Questo libro propone al lettore un vero e proprio percorso guidato per imparare a programmare "facendo". Il vo

459 105 116MB

Italian Pages 288 [275] Year 2005

Report DMCA / Copyright

DOWNLOAD FILE

Polecaj historie

Laboratorio di programmazione in Java
 8850321457, 9788850321452

Table of contents :
Scan-190612-0001_1L_risultato
Scan-190612-0001_2R_risultato
Scan-190612-0002_1L_risultato
Scan-190612-0002_2R_risultato
Scan-190612-0003_1L_risultato
Scan-190612-0003_2R_risultato
Scan-190612-0004_1L_risultato
Scan-190612-0004_2R_risultato
Scan-190612-0005_2R_risultato
Scan-190612-0006_1L_risultato
Scan-190612-0006_2R_risultato
Scan-190612-0007_1L_risultato
Scan-190612-0007_2R_risultato
Scan-190612-0008_1L_risultato
Scan-190612-0008_2R_risultato
Scan-190612-0009_1L_risultato
Scan-190612-0009_2R_risultato
Scan-190612-0011_1L_risultato
Scan-190612-0011_2R_risultato
Scan-190612-0012_1L_risultato
Scan-190612-0012_2R_risultato
Scan-190612-0013_1L_risultato
Scan-190612-0013_2R_risultato
Scan-190612-0014_1L_risultato
Scan-190612-0014_2R_risultato
Scan-190612-0015_1L_risultato
Scan-190612-0015_2R_risultato
Scan-190612-0016_1L_risultato
Scan-190612-0016_2R_risultato
Scan-190612-0017_1L_risultato
Scan-190612-0017_2R_risultato
Scan-190612-0018_1L_risultato
Scan-190612-0018_2R_risultato
Scan-190612-0019_1L_risultato
Scan-190612-0019_2R_risultato
Scan-190612-0020_1L_risultato
Scan-190612-0020_2R_risultato
Scan-190612-0021_1L_risultato
Scan-190612-0021_2R_risultato
Scan-190612-0022_1L_risultato
Scan-190612-0022_2R_risultato
Scan-190612-0023_1L_risultato
Scan-190612-0023_2R_risultato
Scan-190612-0024_1L_risultato
Scan-190612-0024_2R_risultato
Scan-190612-0025_1L_risultato
Scan-190612-0025_2R_risultato
Scan-190612-0026_1L_risultato
Scan-190612-0026_2R_risultato
Scan-190612-0027_1L_risultato
Scan-190612-0027_2R_risultato
Scan-190612-0028_1L_risultato
Scan-190612-0028_2R_risultato
Scan-190612-0029_1L_risultato
Scan-190612-0029_2R_risultato
Scan-190612-0030_1L_risultato
Scan-190612-0030_2R_risultato
Scan-190612-0031_1L_risultato
Scan-190612-0031_2R_risultato
Scan-190612-0032_1L_risultato
Scan-190612-0032_2R_risultato
Scan-190612-0033_1L_risultato
Scan-190612-0033_2R_risultato
Scan-190612-0034_1L_risultato
Scan-190612-0034_2R_risultato
Scan-190612-0035_1L_risultato
Scan-190612-0035_2R_risultato
Scan-190612-0036_1L_risultato
Scan-190612-0036_2R_risultato
Scan-190612-0037_1L_risultato
Scan-190612-0037_2R_risultato
Scan-190612-0038_1L_risultato
Scan-190612-0038_2R_risultato
Scan-190612-0039_1L_risultato
Scan-190612-0039_2R_risultato
Scan-190612-0040_1L_risultato
Scan-190612-0040_2R_risultato
Scan-190612-0041_1L_risultato
Scan-190612-0041_2R_risultato
Scan-190612-0042_1L_risultato
Scan-190612-0042_2R_risultato
Scan-190612-0043_1L_risultato
Scan-190612-0043_2R_risultato
Scan-190612-0044_1L_risultato
Scan-190612-0044_2R_risultato
Scan-190612-0045_1L_risultato
Scan-190612-0045_2R_risultato
Scan-190612-0046_1L_risultato
Scan-190612-0046_2R_risultato
Scan-190612-0047_1L_risultato
Scan-190612-0047_2R_risultato
Scan-190612-0048_1L_risultato
Scan-190612-0048_2R_risultato
Scan-190612-0049_1L_risultato
Scan-190612-0049_2R_risultato
Scan-190612-0050_1L_risultato
Scan-190612-0050_2R_risultato
Scan-190612-0051_1L_risultato
Scan-190612-0051_2R_risultato
Scan-190612-0052_1L_risultato
Scan-190612-0052_2R_risultato
Scan-190612-0053_1L_risultato
Scan-190612-0053_2R_risultato
Scan-190612-0054_1L_risultato
Scan-190612-0054_2R_risultato
Scan-190612-0055_1L_risultato
Scan-190612-0055_2R_risultato
Scan-190612-0056_1L_risultato
Scan-190612-0056_2R_risultato
Scan-190612-0057_1L_risultato
Scan-190612-0057_2R_risultato
Scan-190612-0058_1L_risultato
Scan-190612-0058_2R_risultato
Scan-190612-0059_1L_risultato
Scan-190612-0059_2R_risultato
Scan-190612-0060_1L_risultato
Scan-190612-0060_2R_risultato
Scan-190612-0061_1L_risultato
Scan-190612-0061_2R_risultato
Scan-190612-0062_1L_risultato
Scan-190612-0062_2R_risultato
Scan-190612-0063_1L_risultato
Scan-190612-0063_2R_risultato
Scan-190612-0064_1L_risultato
Scan-190612-0064_2R_risultato
Scan-190612-0065_1L_risultato
Scan-190612-0065_2R_risultato
Scan-190612-0066_1L_risultato
Scan-190612-0066_2R_risultato
Scan-190612-0067_1L_risultato
Scan-190612-0067_2R_risultato
Scan-190612-0068_1L_risultato
Scan-190612-0068_2R_risultato
Scan-190612-0069_1L_risultato
Scan-190612-0069_2R_risultato
Scan-190612-0070_1L_risultato
Scan-190612-0070_2R_risultato
Scan-190612-0071_1L_risultato
Scan-190612-0071_2R_risultato
Scan-190612-0072_1L_risultato
Scan-190612-0072_2R_risultato
Scan-190612-0073_1L_risultato
Scan-190612-0073_2R_risultato
Scan-190612-0074_1L_risultato
Scan-190612-0074_2R_risultato
Scan-190612-0075_1L_risultato
Scan-190612-0075_2R_risultato
Scan-190612-0076_1L_risultato
Scan-190612-0076_2R_risultato
Scan-190612-0077_1L_risultato
Scan-190612-0077_2R_risultato
Scan-190612-0078_1L_risultato
Scan-190612-0078_2R_risultato
Scan-190612-0079_1L_risultato
Scan-190612-0079_2R_risultato
Scan-190612-0080_1L_risultato
Scan-190612-0080_2R_risultato
Scan-190612-0081_1L_risultato
Scan-190612-0081_2R_risultato
Scan-190612-0082_1L_risultato
Scan-190612-0082_2R_risultato
Scan-190612-0083_1L_risultato
Scan-190612-0083_2R_risultato
Scan-190612-0084_1L_risultato
Scan-190612-0084_2R_risultato
Scan-190612-0085_1L_risultato
Scan-190612-0085_2R_risultato
Scan-190612-0086_1L_risultato
Scan-190612-0086_2R_risultato
Scan-190612-0087_1L_risultato
Scan-190612-0087_2R_risultato
Scan-190612-0088_1L_risultato
Scan-190612-0088_2R_risultato
Scan-190612-0089_1L_risultato
Scan-190612-0089_2R_risultato
Scan-190612-0090_1L_risultato
Scan-190612-0090_2R_risultato
Scan-190612-0091_1L_risultato
Scan-190612-0091_2R_risultato
Scan-190612-0092_1L_risultato
Scan-190612-0092_2R_risultato
Scan-190612-0093_1L_risultato
Scan-190612-0093_2R_risultato
Scan-190612-0094_1L_risultato
Scan-190612-0094_2R_risultato
Scan-190612-0095_1L_risultato
Scan-190612-0095_2R_risultato
Scan-190612-0096_1L_risultato
Scan-190612-0096_2R_risultato
Scan-190612-0097_1L_risultato
Scan-190612-0097_2R_risultato
Scan-190612-0098_1L_risultato
Scan-190612-0098_2R_risultato
Scan-190612-0099_1L_risultato
Scan-190612-0099_2R_risultato
Scan-190612-0100_1L_risultato
Scan-190612-0100_2R_risultato
Scan-190612-0101_1L_risultato
Scan-190612-0101_2R_risultato
Scan-190612-0102_1L_risultato
Scan-190612-0102_2R_risultato
Scan-190612-0103_1L_risultato
Scan-190612-0103_2R_risultato
Scan-190612-0104_1L_risultato
Scan-190612-0104_2R_risultato
Scan-190612-0105_1L_risultato
Scan-190612-0105_2R_risultato
Scan-190612-0106_1L_risultato
Scan-190612-0106_2R_risultato
Scan-190612-0107_1L_risultato
Scan-190612-0107_2R_risultato
Scan-190612-0108_1L_risultato
Scan-190612-0108_2R_risultato
Scan-190612-0109_1L_risultato
Scan-190612-0109_2R_risultato
Scan-190612-0110_1L_risultato
Scan-190612-0110_2R_risultato
Scan-190612-0111_1L_risultato
Scan-190612-0111_2R_risultato
Scan-190612-0112_1L_risultato
Scan-190612-0112_2R_risultato
Scan-190612-0113_1L_risultato
Scan-190612-0113_2R_risultato
Scan-190612-0114_1L_risultato
Scan-190612-0114_2R_risultato
Scan-190612-0115_1L_risultato
Scan-190612-0115_2R_risultato
Scan-190612-0116_1L_risultato
Scan-190612-0116_2R_risultato
Scan-190612-0117_1L_risultato
Scan-190612-0117_2R_risultato
Scan-190612-0118_1L_risultato
Scan-190612-0118_2R_risultato
Scan-190612-0119_1L_risultato
Scan-190612-0119_2R_risultato
Scan-190612-0120_1L_risultato
Scan-190612-0120_2R_risultato
Scan-190612-0121_1L_risultato
Scan-190612-0121_2R_risultato
Scan-190612-0122_1L_risultato
Scan-190612-0122_2R_risultato
Scan-190612-0123_1L_risultato
Scan-190612-0123_2R_risultato
Scan-190612-0124_1L_risultato
Scan-190612-0124_2R_risultato
Scan-190612-0125_1L_risultato
Scan-190612-0125_2R_risultato
Scan-190612-0126_1L_risultato
Scan-190612-0126_2R_risultato
Scan-190612-0127_1L_risultato
Scan-190612-0127_2R_risultato
Scan-190612-0128_1L_risultato
Scan-190612-0128_2R_risultato
Scan-190612-0129_1L_risultato
Scan-190612-0129_2R_risultato
Scan-190612-0130_1L_risultato
Scan-190612-0130_2R_risultato
Scan-190612-0131_1L_risultato
Scan-190612-0131_2R_risultato
Scan-190612-0132_1L_risultato
Scan-190612-0132_2R_risultato
Scan-190612-0133_1L_risultato
Scan-190612-0133_2R_risultato
Scan-190612-0134_1L_risultato
Scan-190612-0134_2R_risultato
Scan-190612-0135_1L_risultato
Scan-190612-0135_2R_risultato
Scan-190612-0136_1L_risultato
Scan-190612-0136_2R_risultato
Scan-190612-0137_1L_risultato
Scan-190612-0137_2R_risultato
Scan-190612-0138_1L_risultato
Scan-190612-0138_2R_risultato
Scan-190612-0139_1L_risultato
Scan-190612-0139_2R_risultato

Citation preview

Laboratorio di programmazione in Java

Autori: Paolo Coppola e Stefano Mizzaro Copyright @ 2004 - APOGEO

Via Natale Battaglia 12 - 20127 Milano (ltaly) Telefono: 02-289981 - Fax: 02-26116334 Email [email protected] U.R.L. www.apogeonline.com

ISBN 88-503-2145-7 Impaginazione elettronica con l11F){ 2e Editor: Alberto Kratter ThaJer Copertina e progetto grafico: Enrico Marcandalll Responsabile di produzione: Vitiano Zaini

Tutti i diritti sono riservati a norma di legge e a norma delle convenzioni internazionali. Nessuna

parte di questo libro può essere riprodotta con sistemi elettronici, meccanici o altri, senza l'autoriz1..azione scritta dell ' Editore. Nomi e marchi citati nel testo sono generalmente depositati o registrati dalle rispettive case produttrici .

Ad Anna, che conosce i metodi e capisce le eccezioni e a Giorgia, che è ancora in compilazione, ma che presto sarà in esecuzione. A Federico, per tutto quello che mi stai insegnando.

Indice

Prefazione

ix

Premessa

xi

Gli esercizi

1

Capitolo I I primi passi 1. 1 I nostri primi programmi in Java . . . . . . . 1.2 I mattoni di base dei programmi Java . .. . 1.2. 1 I messaggi di errore del compilatore . 1.2.2 I tipi di dato primitivi . . . . . . 1.2.3 I letterali e le sequenze di escape 1.2.4 Gli operatori fra valori interi . 1.2.5 L' operatore di modulo ''%" . 1.2.6 Il tipo di dato boolean . . . 1.2.7 Promozioni e cast . . . .. . 1.2.8 Le convenzioni per gli identificatori e i commenti 1.3 Tecniche, problemi e trucchi ricorrenti . 1.4 Una classe utile: Leggi. j ava .

IO IO 12 12 15

Capitolo 2 La programmazione strutturata 2.1 Le strutture di controllo di base . . . . . . 2.1. 1 La sequenza di istruzioni . . . . . 2.1.2 L' istruzione di selezione if / else 2.1.3 Gli if /else annidati . . . . . . . 2.1.4 L' istruzione while . . . . . . . . 2.1.5 Lo sviluppo incrementale dei programmi 2.1 .6 I cicli annidati . . . . . . . 2.2 Le strutture di controllo avanzate . 2.2. 1 L' istruzione switch / case 2.2.2 L' istruzione do/while ..

19 19 19 21 22 24 24 25 26 26 27

3 3 6 6 7

8 8 9

vi

Indice

2.3

2.2.3 L'i truzione for . . . . . . . . . 2.2.4 I for annidati . . . . . . . .. . 2.2.5 Le istruzioni break e continue 2.2.6 Approfondimenti: for , cicli annidati,++ e - Glj array . . . . . . . . .. . . 2.3.1 Array unidjmen ionaJi . . . . . . . . . 2.3.2 Array multimen ionaJi . . . . . . . . . 2.3.3 E ercizi di approfondimento sugli array

Capitolo 3 I metodi e l'occultamento delle informazioni 3.1 I metodi . . . . . . . . . . . . . . 3.1.1 Introduzione ai metodi . . . 3 .1. 2 Parametri per valore e per riferimento 3.1.3 La vi ibilità delle variabili 3.1.4 Saper u are i metodi . . . . . . . 3.1.5 Metodi e array . . . . . . . . . . 3.1.6 Imparare a progettare un metodo 3.2 La ricor ione . . . . . . . . . . . . . . . 3.3 I ti pi di dato a tratti . . . . . . . . . . . 3.3. l U are e modificare un semplice TDA 3.3.2 Metodi in ver ione procedurale e funzionale . 3.3.3 I CO truttori . . . . . . . . . . . . 3.3.4 Definire nuovi TDA . . . . . . . . 3.3.5 L'occultamento delle informazioni Capitolo 4 La programmazione orientata agli oggetti 4 .1 Dai tipi di dato a tratti agli oggetti . . . . . . . 4 .1. l Definire e usare oggetti . . . . . . . . 4 . 1.2 L'uso di this e della notazione puntata 4.2 Eredità e polimorfi mo . . . . . . . . . 4 .2. l L'ereditarietà e la sov rascrittura . . . . 4.2.2 L' uso di super . . . . . . . . . . . . 4.2.3 li polimorfi mo, il late-binding, le clas i a tratte e le interfacce 4.2.4 Definire gerarchie . . . . . . . . . . . . . . . . . . . . . .

27 28 29 30 35 35 36 38

41 41 41 45

46 47 48 51 53 57 57 59

60 61 62

65 65 65 70 76 76 78 80 85

Capitolo 5 fava avanzato

5. 1

Le API 5. 1.l 5. 1.2 5.1.3

di Java . . . . . . Le eccezioni . . . La clas e 0b j ect Package e documentazione dell e API Java .

89 89 89 91 92

vii

Indice

5.2

Le interfacce grafi che . . . . . . . 5.2. 1 Le prime interfacce grafiche 5.2.2 A coltatori e adattatori .. . 5.2.3 I ge tori del Iayout e gli eventi . 5.2.4 Gli applet e come di egnare ui componenti .

Le soluzioni apitolo 6 oluzioni del capitolo J 6. 1 I no tri primi programmi in Java . . . . . . . 6.2 I mattoni di ba e dei programmi Java . . . . 6.2.1 I me aggi di errore del compilatore . 6.2.2 I tipi di dato primitivi . . . . . . 6.2.3 I letterali e le equenze d.i e cape 6.2.4 Gli operatori fra valori interi . 6.2.5 L' operatore di modulo' '%" . 6.2.6 U tipo di dato boolean . . . 6.2.7 Promozioni e ca t . . . . . . 6.2.8 Le convenzioni per gli identificatori e i commenti 6.3 Tecniche, problemi e trucchi ricorrenti . . . . . . . . . . ap itolo 7 oluzioni del capitolo 2 7.1 Le trutture di controllo di base . . . . . . 7.1 .1 La equenza di i truzioni . . . . . 7. 1.2 L' istruzione di selezione i f / else 7.1.3 Gliif/elseannidati . .. .. . . 7. l.4 L' i truzione while . . . . . .. . 7. l.5 Lo viluppo incrementale dei programmi 7 .1.6 I cicli annidati . . . . . . . 7.2 Le trutture di controllo avanzate . 7. 2. 1 L' i truzione switch/case 7.2.2 L'i truzione do/while 7.2.3 L' i truzione for . . . .. . 7.2.4 I for annidati .. . . . . . 7.2.5 Le i truzioni break e continue 7.2.6 Approfondimenti : for , cicli annidati,++ e - 7.3 Gli array . .. . . . . . .. .. . 7.3 .1 Array unidimensionali . . . . . . . . . 7.3 .2 Array multidimen ionali . . .. . . . . 7.3.3 E ercizi di approfondimento sugli array

94 94

95 97 104

107 109 109 111

111 112 11 3 114 114 115 120 122 122

133 133 133 136 138

139 140 145 147 147 148 149

151 152

153 157 157

159 161

viii

Capitolo 8 Soluzioni del capitolo 3 8. 1 I metodi . . . . . . . . . . . . . . . . . . . 8 . 1.1 Introdu zione ai metodi . . . . . . . . 8.1 .2 Parametri per valore e per riferimento 8.1 .3 La vi ibilità delle variabili 8.1.4 ap r u are le funzioni . . . . . . 8.1.5 Metodi e array . . . . . . . . . . 8.1 .6 Imparare a progettare un metodo 8.2 La ricor ione . . . . . . . . . . . . . . . 8.3 I tipi di dato a tratti . . . . . . . . . . . 8.3 . 1 U are e modificare un empli ce TDA 8.3.2 Metodi in ver ione procedurale e fun zion ale . 8.3.3 l CO truttori . . . . . . . . . . . . 8.3.4 D finire nuovi TD 8.3 .5 L' occultamento delle informazioni

Indice

165 165 165 169 170 170 171 175 180 192 192 198 200 201 207

apitolo 9 Soluzioni del capitolo 4 2 1I 9 . 1 Dai tipi di dato a tratti agli ogg tti . . . . . . . 2 11 9. 1.1 Definir u are oggetti . . . . . . . . 2 11 9. 1.2 L' u o di this d Ila notazione puntata 220 9.2 Er dit e polimorfi mo . . . . . . . . . 229 9.2. 1 L'ereditarietà e la ovra crittura . . . 229 9.2.2 L' u o di super . . . . . . . . . . . 23 1 9.2.3 Il polimorfi mo, il late-binding, le eia i a tratte e le int rfacce 234 9.2.4 D finire gerarchie . . . . . . . . . . . . . . . . . . . . . . 24 1 Capitolo IO Soluzioni del capitolo 5 IO. I Le API di Ja a . . . .. . I O. I . I Le eccezioni . . . 10. 1.2 Lacla e Object I 0.1.3 Package e documentazion d Il API Java . I0 .2 Le interfacce grafiche . . . . . . I 0.2. 1 Le prime interfacce grafiche . . . . . . . . I 0.2.2 I ge tori del layout e gli eventi . . . . . . . 10.2.3 Gli applet e come di gnare ui compon nti

247 247 247 250 252 253 253 257 262

Una conclu ione?

267

Prefazione

Quel ol che pria d'amor mi cald il petto Di bella verità m'avea co erto Provando e riprovando, il dolce a petto. Paradiso, canto terza, 1-3. el uo viaggio attraver o il Paradi o, Dante gujdato da Beatrice (il ole che per pri mo cald d' amore il uo cuore), che provando e riprovando (cioè argomentando e di -provando, ovvero controargomentando) gli rivela la natura della verità. li "provando e riprovando" dj Beatrice, reinterpretato come le" en ate e perienze" iterate e reiterate dj Galileo, è una deUe e pre ioru più acre e care delJa cienza m derna. Tre ecoli dopo Dante, aranno degli alliev i ideal i w Galileo a ceg)jerlo com motto delJa prima accademja cientifica moderna, queU' Accademia del Ciment eh i po e come obiettivo di verificare con metodo rigoro amente p rimentale (pr vando e riprovando) i principi delJ a filo ofia naturale. La cienza moderna na ce dall'o ervazione ripetuta, dall 'e ercizio, dalla verifica, dall'errore e dall a ua correzione. La compren ione cientifica (anzi, la cienza te a) caturi ce empre da un problema a cui non a dare ri po ta. Per tro are oluzi n i inventano tecniche, teorie, congetture. Molte dj e e non uperano il vaglio dell ' e perimento, e dal l' errore comme o e rile ato na cono a.I tre tecruch , altre t orie, altr congetture, fin o a quando la oluzione al problema appare chiara, limpida, ·pe o empi ice ed elegante. La ricerca dell a olu zione ad un problema ha finalmente part rito una teoria generale, che piega eia i di problemi imili e forni ce tecniche generali , bell e e potenti . Lo tudio delle di cipline cientifi che troppo pe o solo tudio di que te teorie genera.li . Impariamo l'anaJi i matematica a partire da.Ila defi nizione di fun zione continua e di limite, la meccan ica a partire da.I le leggi fondamenta.li che legano forza, ma a e moto, l'informatica a partire dal.la defi njzione dj un linguaggio w programmazione. Ma co l facendo perdiamo il sen o te o della pratica di cienza, che inte uta dj probl emi , di prove, dj riprove e w w -prove. È ev idente che non arebb n ato ripercorrere ogru volta la trada dei no tri predece ori, ripetere i loro tentativi falliti, ri coprire le loro tecruche. Ma I' a etticità delJe teorie generali non deve impedire di porcarci le maru , w provare quegli trumenti ui problemi che ci appa ionano, dj inventare nuove appljcazionj della teoria. La cienza entra in noi , anche oggi, olo attraver o I' e ercizio, il confro nto con quelli che hanno tentato lo

1

I primi passi

Contenuto I.I

I nostri primi programmi in lava

1.2

I ma/Ioni di base dei programmi lava

1.3

Tecniche, problemi e trucchi ricorrenti

1.4

Una classe utile: Leggi . j ava

Questo è un libro da non leggere. Assolutamente. Da un libro che non abbiamo letto . . .

1.1

I nostri primi programmi in Java

Dove si impara a editare (scrivere), compilare ed eseguire un semplice programma in Java. Per ora vediamo solo i rudimenti; l'obiettivo è familiarizzare con l'ambiente che useremo per tutto il resto del libro e con i meccanismi del ciclo editing-compilazioneesecuzione. Per risolvere gli e ercizi in questo paragrafo dovete saper usare un calcolatore, con un sistema operativo qualsiasi (Linux, Windows, MacOS, ... ). A dire il vero, questo paragrafo contiene esercizi estremamente semplici; approfittatene anche per prendere confidenza con il sistema operativo e gli applicativi usati (editor, shell dei comandi, esplorazione del file system, ecc.). Prima di cominciare, create una cartella in cui mettere tutti i vo tri primi programmi. Ad esempio, potreste creare e se rei tazione1, ma scegliete il nome, e l'organizzazione dei programmi scritti per risolvere gli esercizi, che più vi aggradano. Abituatevi a farlo sistematicamente. Esercizio 1.1 Più che un esercizio, questa è un ' attività che eseguiamo insieme, passo dopo passo. Avviate, sul vostro caJcolatore, un editor di testi e create il file "CiaoATutti. j ava", nella cartella eserci tazione1. In questo file copiate il programma "CiaoATutti" seguente: / * Il nostro primo programma Java */ class CiaoATutti { public static void main (String[] args) {

I primi pa si

4

System. out . println ( "Ciao a tutti ll I ' ) ; }

È importante che lo in eriate da ta tiera, non con un copia e incoll a da qualche 1to Web! In que to modo, in fatti, cominciate a imparare a crivere i programmi con la ma ima attenzione e con prec i ione: una differenza di un uni co carattere, anche un egno di punteggiatura, o una maiu co la al po to di una rninu cola, può rendere il programma corretto e non e eguibile. Ri cordatevi di alvare il file "CiaoATutti. j ava". Pa ate ora alla hell dei comandi p r compilare ed e eguire il programma. un ' operazione in due pas i. Il primo pa o la compil azione con il comand " j avac": l>javac CiaoATutti.java Se ci ono me agg i di errore, cercate di comprenderli , e ricontrollate attentarnent di aver copiato il programma in modo e atto. Quando capite co a non va , modificat il file "CiaoATutti. j ava" , ricordatevi di alvarlo (!) e ricompil ate. Quando non ci ono errori di compil azione potete pa are al econdo pa ed e eguire il programma, con il comando " j ava":

l>java CiaoATutti Se il programma vi uali zza "Ciao a tutti 111 ", congratulazioni , avete critto il vo tro primo programma in Java. Se siete curio i, con il comando Unix/Linux "ls" (o l'analogo "dir" del DOS, o e plorando il file y tem con uno trumento grafico) av rete notato che c' un nuovo file , "CiaoATutti. class": è il prodotto del compilatore; non vi ualizzatelo, formato da caratteri non tarnpabili !

Esercizio 1.2 [s] Modificate il programma "CiaoATutti" in modo che vi ualizzi "Ciao agli altri! 11 ". Per verificare che la modifica è corretta, al vate, ricompilate e rieseguite. .B.: ( l ) alvate; (2) ricompil ate; (3) rie eguite. È nec ario fare que ti 3 pa i in que to ordine. Esercizio 1.3 Con iderate il codice di "CiaoATutti": vi ono in tutto 19 parole. • Quali ono quelle che potete modificare (aggiungendo o togliendo una lettera qual ia i) enza che il compilatore vi dia errore? • Quali ono quelle che potete modificare enza errori in compil az ione, ma con un errore in e ecuzione? • Quali ono quelle che potete modifi care enza errori in compil azione e enza errori in e ecuzione? Quali tra queste non modificano il ri sultato (viene tampato empre "Ciao agli altri")?

I . I I no tri primi programmi in }ava



5

e i modifica uno degli altri caratteri (parente i, punteggiatura, barre) si ottiene mpre errore in compil azione?

Esercizio 1.4 Copiate il programma "AreaDiUnTriangolo" eguente, aJvandolo in un file 'AreaDiUnTriangolo. j ava": / * Programma che calcola l ' area di un triangolo*/ class AreaDi UnTriangolo { public stat ic void main (String[] args) { int base; i nt altezza; i nt area; base = 4; altezza = 10; area = base• altezza / 2; System . out.println(area); }

Cercate di capire co a fa. uccede.

Poi compil atelo ed e eguitelo, e aminando quello che

Esercizio 1.5 Rip tete

l'e erc izio 1.3 facendo "AreaDiUnTriangolo" dell e ercizio precedente.

riferiment

aJ

codice

di

E ercizio 1.6 [s] Modificate il programma "AreaDiUnTriangolo" d ll ' e erci zio 1.4 per poter calcolare l'area di un triangolo con base 124 e altezza 32. ri ompilate, e rie eguite.

aJvate,

E ercizio 1.7 [S] Co a succede e, nel program ma "AreaDiUnTriangolo" del1'e ercizio 1.4, i valori di base e altezza Perché?

ono, ad e empio , entrambi 3?

Esercizio 1.8 [S] Copiate il programma "MassimoDiDue"

guent

/ * Programma per calcolare il massimo fra 2 cifre* / i mport java.io.•; class MassimoDiDue { public static vo i d main(String[] args) th rows IOException { int a , b; a = System. in .read(); b = System .in.read(); i f (a>b) System.out.println("Il massimo e ' il pr imo ' ); else System.out.println("Il massimo e' il secondo"); } }

I primi pa si

6

Poi com pilatelo ed e eguitelo u ari dati di prova.

Esercizio 1.9 [S) Modificate il programma "MassimoDiDue" precedente per far che vi uali zzi il me aggio "In eri ci le due cifre dj cui vuoi calcolare il ma imo ' prima di fermar i per l'input da utente. Suggerimento Si u a l'i truzione "System. out. println" .

E ercizio 1.10 Prendete il programma CiaoATutti de ll' e ercizio 1.1

alvat lo in un file dj nom ciaoatutti . j ava ( enza le lettere maiu cole). Pro at a compilar che comando dovete u are? Provate poi a e eguire: che comando dovete u are?

Suggerimento ate il comando 1s ( otto Uni /Linux ; dir da DO ecc.) per edere quale file è tato creato dal compilatore . ..

E ercizio 1.11 [S) Ripetet l'e ercizio precedente u ando un fil CiaoATutt i ( enza l'estensione . j ava).

1.2

di

n m

I mattoni di base dei programmi Java

Dove i corru ncia a tudiare il linguaggio Java vero e proprio. i inc ntran i matt ru di base, o ia gli elementi di granularità più fine d I linguagg io: gli id ntifi at ri , i tipi di dato prirrutivi, i lettera.li, le equenze di e cap , le variab ili , gli p rat ri I e pre ioni, l'a egnamento, i commenti . i tratta anche dei con tti di pr m zi n di tipo e ca t. Que ti elementi ricorreranno poi nei programmj ' eri ' eh ri r t più avanti. Inoltre, farete ancora un po ' dj pratica ul i I editing- mpilazi n e ecuzione e criverete i primi emplici programmi cr ati da 1.

1.2.1

I messaggi di errore del compilatore

Esercizio 1.12 [S) Con iderate il eguente programma: class Identif icato r i { public static void main{String[] args) { int Xj }

(in realtà è un programma e tremamente povero, che non fa a olutamente nulla di vi ibil e, ma per ora ci ba ta). Provate a moilificare il nome d ll ' identifi catore dj ariabile x in maniera non con entita (rivedete le regole intattiche p r gli identificatori). Ad e empio provate, in equenza, a o tituire x con class (che è una parola ri rvata), con 1 x (che corruncia con un carattere non con entito), o con x 1 (' x pazio un ', che contiene il carattere pazio, non con entito). Ricompilate dopo ogni m difica e cercat ili capire i me aggi di errore del compil atore.

1.2 l ma11011i di base dei programmi l a va

7

E ercizio 1.13 Ripetete l'e ercizio precedente, per modificando il nome del programma (anche que to è un identi fi catore) invece del nome della variabile.

1.2.2 I tipi di dato primitivi Esercizio 1.14 [s] Rivedete l' e ercizio 1.7. Riprendete il programma AreaDiUnTr i angolo e modificate le dichiarazioni delle variabili area , base e altezza per far ì che il programma fun zioni corr ttament anch l' area non un valore intero. Esercizio 1.15 [S] Verificate la correttezza dei valori ma imi e minimi eh è po ibile memorizzare nelle vari abili di tipo byte, short , int e long , crivendo un breve programma in cui : • dichiarate 4 variabili (una per ogni tipo) di nome b, s , i ed l ; • a egnate a que te 4 variabili un valore piu grande del ma imo po i bile; • fa te vi uaJizzare (con System. out. println) il valore che è in realtà contenuto nelle variabili .

Suggerimento

Come a rete capito, tutti i programmi hanno la te a

truttura: class ' NomeProgramma " { public s t atic vo i d main(String[J arg s ) { }

do e, al po to di " NomeProgramma" ci va il nome del programma, e al po to dei puntini " ... " le i truzioni che compongono il pr gramm a, in equenza. In que to ca o il programma arà (le parti da completare ono quelle fra virgolette " o, come dicono gli informatici, doppi apici): / * Programma per veri f ic are • ... • * / class Ver i f ic aMassimi Minimi { public static vo i d main (Stri ng[J arg s ) { ' dic hia ra zione de l le 4 variab i l i "

b = (by t e ) (127 + 1) ; s = (short)( ' ... ' );

Syst em.ou t. pr i ntln(b ); System.out. println( s ); Sy st ~m. ou t. pr i ntln( i ) ;

I primi passi

8

Syst em.out.print l n(l ); }

Ricordate che i letterali di tipo long vanno eguiti da una L. E non dimenticate i punti e virgola aJla fi ne di ogni i truzione!

1.2.3

I letterali e le sequenze di escape

Esercizio 1.16 [s] Scrivete un programma che memorizza il caratter ' (apic ) in una variabiJe di tipo e ha r e poi vi ualizza il contenuto della variabile. Suggerimento Avrete bi ogno di un programma con 3 i truzioni: d vrete prima dichiarare la variabile di tipo char, poi a egnarl il alore voluto u ando la equenza di e cape e poi tamparla (u ando la System. out. println).

E ercizio 1.17 Scrivete un programma che memori zza il carattere .. (doppi api ) in una variabile di tipo String e poi vi ualizza il contenuto dell a ariabil (u and la System. out. println). Esercizio 1.18 Scrivete un programma che memorizza tutti i caratteri corri p nd nti alle equenze di e cape in una tringa e poi la vi ualizza.

1.2.4

Gli operatori fra valori interi

Esercizio 1.19 [S] La fo rmula per il caJcolo dell 'area di un trapezio : " omma delle ba i per altezza divi o due". Scrivete un programma AreaDiUnTrapezio che a egna valori a vo tra celta alle variabili b1 , b2 e h e caJco la l' area del trap zio corri pondente. Scrivete un ' unica e pre ione, u ando le parente i dove opportuno. Sugge rimento I piratev i al programma AreaDiUnTriangolo delJ 'e ercizio 1.4 e adattatelo (ba tano minime modifich ).

Esercizio 1.20 Scrivete un programma PerimetroDiUnTriangolo che a egna valori a vo tra celta alle variabili lato1 , lato2 e lato3 e caJcola il perimetro del triangolo corri pondente. Esercizio 1.21 Modificate il programma AreaDiUnTriangolo delJ 'e ercizio l.4 e crivete un programma PerimetroDiUnOuadrato che calcola il perimetro di un quadrato.

1.2 l mattoni di ba e dei programmi la va

9

Esercizio 1.22 Modificate il programma AreaDiUnTrapez i o de ll 'e erci zio 1.19 e crivete un programma Diag onaleDiUnRettangol o che calcola la lunghezza di una diagonale di un rettangolo apendo la ba e e l' altezza. Scrivete un ' unica e pre ione, u ando le parente i dove opportuno. Suggerimento Li truzione y = Math. sqrt ( x) j a egna al la variabile y (che deve e ere di tipo double) il valore della radice quadrata di x.

1.2.5

L'operatore di modulo ''%"

L'operatore di modulo re titui ce il re to de lla divi ione intera. on è un concetto diffi cil : lo i impara alle cuole elementari, ma poi i ha tutto il tempo di dimenticarene. Siccome è un 'operazione molto utile per la programmazione, facciamo la ua cono cenza negli e ercizi egu nti ; lo ritroveremo pe o anche in· eguito . . .

Esercizio 1.23 [S] Qual è il valore a unto dalla variabi le x, di tipo int, dopo ognuno degli a egnamenti eguenti ? X X X X

16 15 16 15

= = = =

I 2; I 2; % 2; % 2;

crivete un breve programma per verificare che lavo tra ri po ta ia corretta. Suggerimento È uffic iente cri ere un programma contenente la dichiarazione de ll a variabi le x e poi i 4 a egnamenti a x dei 4 va lori , ognuno eguito daJl'i truzione di vi uali zzazione del valore di x (System. out. println).

E ercizio 1.24 [S] Scrivete l'i truzione di a egnamento eh a egna alla variabile int ra y il valore O e la variabile intera x è pari, I e x è di pari . cri vete un breve programma p r verifi care che lavo tra oluzione ia corretta. Suggerimento Ripen ate al ri ultato de lle ultime due operazioni de ll eercizio precedente e completate (ed eseguite più vo lte u più valori di x) il programma eguente: I* Programma per ' .. . • * I class PariDispari { publ ic static vo i d main (String[J args) { int y; int x· I '. .. X = Il valore di prova ' y = . . . ' ; Il espressione da trovare ... Sy stem .out. pr intln( y) ;

..

}

I primi pa

10

1.2.6

Il tipo di dato boolean

Il tipo boolean è il più emplice di tutti , dato che le variabili di quel tipo po ono a umere olo i valori true e false. Eppure pe o ri ulta di di ffic ile compren ione ai neofiti .

Esercizio 1.25 [S] Scrivete l'i truzione di a egnamento che as egna alla variabile booleana p il valore true e la variabile intera x è pari , false altrimenti . Scrivete un breve programma per verificare che lavo tra oluzione ia corretta.

Suggerimento Ripen ate aJl 'e ercizio 1.24 e u ate l'operatore di uguaglianza " ==" nella parte destra dell' a egnamento. Fate attenzione: la modifi ca è minima, ma richiede un alto logico ...

Esercizio 1.26 [S] Scrivete l'i truzione di a egnamento che a egna al la variabile booleana p il val ore true e la variabile intera x ha un val ore po itivo (maggior uguale a zero), false altri menti . Scri vete un breve programma per verificare eh la vo tra oluzione ia corretta.

Suggerimento Que to e ercizio e quelli immedi atamente ucce ivi ono varianti minime del precedente.

Esercizio 1.27 [S] Scrivete l'i truzione di as egnamento che a egna al la ariabile boo leana p il valore true e la variabile intera x ha un valore po itivo (maggiore o ugual e a zero) o pari , false altrimenti. Scrivete un breve programma per erificare che la vo tra oluzione ia corretta.

Suggerimento U ate gli operatori log ici.

Esercizio 1.28 [S] Scrivete l'i truzione di as egnamento che a egna al la variabil booleana p il valore true e la variabile intera x ha un val ore po iti vo (maggior o uguale a zero) e pari, false al trimenti. Scrivete un breve programma pe r eri ficare che la vo tra oluzione ia corretta.

Esercizio 1.29 [S] Scri vete I' i truzione di a egnamento che a egna alla variabile bool eana p il val ore true e la variabile intera x ha un valore po itivo compre o in uno dei eguenti intervalli : (15 , 18], (39,45] , [91 ,104], false altrimenti. Scrivete un breve programma per verificare che la vo tra oluzione ia corretta.

1.2.7

Promozioni e cast

Esercizio 1.30 [S] Scrivete un breve programma che: • dichiara due variabili , i di tipo int e b di tipo byte ;

1.2 I ma11011i di base dei programmi l a va

JJ

• a egna il a.lore 10 aJla variabile b; • copia il vaJore della variabile b nella variabile i (dovete crivere un a egnamento nel quaJe non compaia nuovamente il letteraJe 10, ma olo I variabili). Tutto dovrebbe funzionare enza ne un problema. Modificat poi il programma per cambiare i ruoli di b e i : a gnate 10 aJla ariabile i e poi copiate il vaJore della variabile i nella variabile b. Co a u cede? Perché? Come rimediare? Perché prima della modifica non c'erano problemi ? Co a uccedeva?

Esercizio 1.31 [S] Rifl ettete ul programma eguente: class APerBDi vis oB { public static vo i d main (String[] args) { int a; i nt b; i nt e;

a

2000000000;

b = 2000000000;

e = a * b; e = e I b; System.out.println(c); }

Quale ri ullato vi a pettate? Ri pondete prima di provare ad e eguirlo, poi provate ad e guirlo e cercate di capire perché non è come pen ate . ..

Esercizio 1.32 [S] Dite che co a cambia e modificate il programma precedente co ì: class APerBDiv isoB { publ ic static void main (String[] args) { int a; int b; i nt e ; a 2000000000; b = 2000000000; e = a * b / b;

System . out . println(c);

I primi passi

12

1.2.8

Le convenzioni per gli identificatori

i comm nti

Esercizio 1.33 [s] Riprendete tutti i programmi ritti m r pettato le convenzioni per gli id ntificat ri . Modi

te

fa tto.

E ercizio 1.34 [s] Riprendete tutti i pr gramm_i dove opportuno. U ate il tipo di comm nt più

* I'

1.3

o

"Il ... ").

Tecniche, problemi e trucchi ricorrenti

Esercizio 1.35 [S] lmmaginat (e ne un altro). Scrivete u and I' p rat r a egnamento che as gna alla ariabil y il al r è " I ". Scrivete un breve programma per

Nota Anche e que ta oluzi n fu nzi n , n n po ibile: i vedano gli e ercizi gu nti .

m nt I migli

Esercizio 1.36 [S] Immaginate che la ariabil x po ne un altro). ate, invece dell 'operatore e ndizi nal "%" e cri vete un ' i truzione di a egnam nto eh a n al i e x O e il va lore O e x è I . Scri vete un breve programma o luzione è corretta.

Suggerimento Se a y a egnate x + 1, il ri ultat vale O, ma e x vale I in y vi ritrovate il valore 2. " modulo 2" ... Nota A nche que ta olu zione, pur fun zionante, non po ibile: i veda l'e ercizio eguente.

la mi li

1.3 Tecniche, problemi e trucchi ricorrenti

13

Esercizio 1.37 [S] In rea ltà, nei due e erc izi precedenti g li operatori condi zional e " ?: " e modulo"%" non ono nece ari . Anzi, ono di gran lunga upe rAui e i può fare di meglio e nza. Come? Scrivete un breve programma per verifi are c he lavo tra oluzione corretta. Suggerimento Ricordatevi c he abbi amo detto c he x può a umere solo i valori O o 1, c hiedetevi quanto deve valere x + y, e ri olvete l'equazione ... No ta Que ta oluzione è di gran lunga migliore delle precedenti . Vi pu embrare un dettag lio, ma è importante e volete e ere dei buoni programmatori.

Esercizio 1.38 [S] Scrivete un 'e pres ione per il calcolo del valore a oluto di un numero x. Scrivete anc he un bre e programma conte nente ta le e pre ione pe r controllarne la correttezza.

Suggerimento U ate l'operatore condi zionale " ? : ".

Esercizio 1.39 [S] State reaJizzando un gioco da tavolo in Java e dovete ge tire il turno fra i vari giocatori. Per fare ci usate una variabile turno , di tipo int . Supponiamo per emplicità che ci iano 2 giocatori; quindi turno dovrà a umere in seque nza i valori O, I, O, L, O, I , ... Scrivete I' i tru zione di a egnamento che dal alore corrente di turno calcola il valore ucce ivo.

Suggerimento no?

on vi arete mica già dimenticati gli e e rc izi 1.35- 1.37,

Esercizio 1.40 [S] Con riferimento aJl 'e ercizio precedente, upponiamo ora che, ne l no tro gioco da tavolo, ci iano 4 giocatori ; quindi turno dovrà a sumere in equenza i valori O, J, 2, 3, O, I, 2, 3, O, ... e co ì via. Completate il programma egue nte, crivendo l' i truzione di a egnamento c he a egna di volta in vo lta a turno il valore corretto ulla ba e de l valore precedente.

Suggerimento Quali po ono e ere divi sione di un numero pe r 4 ?

valori a unti dal re to de lla

class Turno { public static vo i d main(String [ J args) { int turno ; int i; tu rn o = 0; i = 0; while (i= 0 ) y = y + 1;

else y

=

y

+

2;

Esercizio 2.9 [S] Scrivete un ' istruzione di a egnamento (che u a l'operatore condi zionale ? : ) equiva lente al la eguente istruzione i f. if (x >= 0 ) y = y + 1;

Esercizio 2.10 [s] Scrivete un ' i truzione i f / else equivalente al la eguente i truzione di a egnam ento. Z =

( X >=

0

&&

X %

2 == 1) ? 0: 1j

Esercizio 2.11 [S] A volte l'istruzione i f / else e l' operatore condizio nale ? : non ono interscambiabili in maniera immedi ata. Quali istruzioni di a egnamento (c he u ano l' operatore condi zionale ? : ) dovete c ri vere per ottenere un frammento di codice equi valente al la eguente istru zione i f / else ? if ( x >= 0 ) y = y + 1;

el se z = z

+ 1;

Sugge rimento Per prima cosa, riscri vete I' i f / else usando due i f . ..

Esercizio 2.12 Scrivete un breve programma per il calcolo del valore a oluto di un numero x. (L'avete già fatto ne ll 'esercizio 1.38 u ando l' operatore condiziona le. Ri fatelo usando I' i f / else.)

2.1.3

Gli i f / else annidati

Esercizio 2.13 Scrivete un frammento di programma che vi ual izza " yeah " e la variabil e x di tipo int è positiva e pari, e vi uali zza " s i gh" altrimenti . Scrivetene due versioni: la prima usando l'operato re di and logico, la seconda con i f annidati (fate attenzione !! ).

2. 1 le trutture di controllo di base

23

Esercizio 2.14 [S] Alice deve decidere e u cire ta era con Bob. Se Bob viene a prenderla con la Ferrari allora u cirà con lui , ma olo e lui non indo a i oliti brutti s imi moca sini. Se invece non viene a prenderla con la Ferrari u cirà con lui olo e lui non ha gli occhiali da ole. Alice ha però paura di emozionar i quando vede Bob, e quindi per icurezza decide di crivere un programmino che faccia la celta per le i econdo que ti criteri. Il programmino avrà 3 variabili bool eane boolean ferrari; boolean mocassini; boolean occhialiDaSole; a cui assegnerà il valore opportuno da tastiera (usando Leggi . unBoolean). Seguiranno poi alcune i truzioni che a egnano il va lore opportuno alla variabi le booleana uscita e altre i truzioni che vi ualizzano il me aggio "U ciamo" se la deci ione è positiva. Scrivete tre versioni del programmino u ando ri pettivamente: • 2 i f ann idati; • un solo i f ; • nessun i f .

Esercizio 2.15 Alice decide di modificare il programma per agg iungere un piccolo dettag lio: e Bob non viene in Ferrari , gli di ce " Pezzente! " (il resto rimane invariato). Scrivete il programma u ando: • 2 i f annidati; • un solo if; • nessun if .

Esercizio 2.16 [S] Ri scrivete il frammento di codice eguente u ando l'annidamento else invece dell'annidamento i f (x, y e z sono variabi li di tipo boolean ). i f (X) i f (y)

if (z) System.out.println( "Si, si, si ' ); else System.out.println( "Si, si, no ' ); else System . out . println("Mah ' ); else System.out.println( ' Boh ");

24

La programmazione trutturata

2.1.4

L'istruzione while

E ercizio 2.17 [ ] crivete un programma che vi uaJi zza tutti i numeri da I O a 100, uno p r riga.

Esercizio 2.18 [S] crivete un programma che vi uaJi zza tutti i numeri da l O a I 00. In que to programma, per , non p lete u are i letterali 10 e 100 (per potete u are 9 e 99 ... ).

Esercizio 2.19 [s] crivet un programma che vi uali zza tutti i num ri da 1O a l 00 ulla t

a riga, eparati da uno pazio.

uggerimento L' i truzione System. out. print vi uaJizza argomenti enza andare a capo ...

uoi

E e rei zio 2.20 [ ] cri ve te un programma che i uaJizza rutti i mu Itipi i di 3 fra I O e I 00 (u ate un i f per decidere e un numero è multiplo di 3).

E ercizio 2.21 [ ] cri vete un programma che vi uali zza tutti i multipli di 5 fra I O e 100.

E ercizio 2.22 Scri vete un pr gramma che vi uaJizza tutti i numeri da LO a I (in ordine decr cente).

uggerimento Invece di incrementare i (da 1 a 10), dec r mentatelo (da 10 a 1 ).

E ercizio 2.23 cri ete un programma che vi uali zza tutti i num eri pari da 20 a I (in ordine decr cente). ate un i f p r dec idere e un numero pari . E ercizio 2.24 [s] Scrivete un programma che vi uali zza tutti i numeri pari da I00 a I (in ordine decre cente), ma enza u are l'if.

2.1.S

Lo sviluppo incrementale dei programmi

E ercizio 2.25 [S] crivete il vo tro primo programma eguendo il metodo dell o sviluppo incrementale: viluppate varie ver ioni empre più dettagliate. Il programma deve i uaJi zzar un me aggio che dica e un numero letto da ta tiera durante l' e ecuzione primo o no (un numero primo è divi ibil e olo per I e per e te o).

E ercizio 2.26 [s]

Scrivete un program ma che legge in input u ando Leggi. unDoub l e , due va lori doub l e . Poi legge un vaJore int fra 1 e 2 e vi uali zza il alore double corri pondente (o ia, il primo o il econdo).

25

2.1 Le stnmure di co111rollo di base

Esercizio 2.27 Scrivete un programma che legge in input (con Leggi. unDouble) dj ec i valori double . Poi legge un alore int fra l e IO e i uali zza il valore corri pondente. Esercizio 2.28 (*)

Scrivete un programma che legge in input (con Leggi. unDouble) 100 valori double . Poi legge un valore int fra l e 100 vi ualizza il valore corri pondente.

Nota Se non avete fretta, nei pros irru e ercizi vedremo come farlo con l O righe ili coruce .. .

Esercizio 2.29 [S] Prendete tre bicchleri uguali ed etichettate li con A, B e C. Riempitene uno (per fi are le idee, cegliamo A) dj acqua e uno (B) di vino. Come fate per cambiare il contenuto dei due bicchleri (o ia, per mettere l' acqua nel bicchlere B e il vino nel bicchlere A)? Scrivete in dettaglio i pa i da effettuare (e prima dj decidere e buttare via il libro, fa te anche il pro imo e ercizio ... )

Esercizio 2.30 [S] Scrivete un programma che cam bi a il va lore di du variabili a e b (al la fine dell 'e ecuzione, a deve avere il valore che ba eva all'iruzio, e vicever a). Suggerimento Ba atevi variabile au iliaria.

ull 'e ercizjo precedente e u ate una terza

Esercizio 2.31 [S] Scrivete un programma che calcola la omma de i prirru n numeri (o ia dei numeri fra 1 e n), con n letto in input durante l' e ecuzio ne.

Esercizio 2.32 Scrivete un program ma che calcola il pr dotto dei primj n numeri , con n letto in input durante I e ecuzione (ci ignifica calco lare il fa ttoriale di n). Suggerimento Fate attenzione a non moltiplicar (anche) p r zero . ..

2.1.6

I cicli annidati

Esercizio 2.33 [S) Scrivete un programma che vi uali zza i numeri prirru da 2 a n, con n letto in input durante l'e ecuzione.

Esercizio 2.34 [S] Scrivete un programma che visuali zza i primi n num ri primi, con n letto in input durante l'e ecuzione.

E ercizio 2.35 Scrivete un programma che vi ualizza la omma dei prirru n numeri prirru , con n letto in input durante l'e ecuzione.

Suggerimento Mettete in ieme i programmj degli e ercizi 2 .3 1 e 2.34.

La programmazione trutturata

26

:t ercizio 2.36 Scrivete un programma che vi ua lj zza il prodotto dei prirru n numeri primi, con n letto in input durante l'e ec uzion .

E ercizio 2.37 Scrivete ei programmi che vi uali zzano i eg uenli triangoli di "+" (un programma per ogni triango lo), con i eguenti vincoli : le uniche i truzioru di viuaJi zzaz ione perme e ono System. out. print ( '+ ' ) , System. out. print ( ' ' ) e System. out. println () ; ognuna di que te i truzioni può apparire aJ ma imo una volta in ognuno dei ei programmi . + ++ +++ ++++ +++++ ++++++

+++++ ++++ +++ ++ +

+++++ ++++ +++ ++ +

+ ++ +++ ++++ +++++ ++++++

++ ++++ ++++++ ++++++++ ++++++++++

+

+++ +++++ +++++++

Esercizio 2.38 E eguite il programma dell' e ere izio 2.3 1 dando in input - 5 ...

2.2

Le strutture di controllo avanzate

n programmator pi gro (molto pigro!) potrebbe accontentar i delle trultur di controllo vi te finora, eh con entono di codificare qualsia i algoritmo. Un programmatore profe ioru ta invece deve fare la cono cenza dell e altre trutture di controllo de ll a programmazione trutturata: I' i truzione di e lezione n-aria switch / case, le altre due i truzioni di iterazione do /while e for , le i tru zioru break e continue e gli operatori di incremento ++ e decremento - - . Que te nuove i truzioni non gli perm tteranno di ri olvere più problemi , ma gli con entiranno di farlo in modo meno fati o o. In o mma, i pigri faranno più fatica. el fare la cono cenza con que ti nuov i trumenti avremo l' occa ione di approfondire quanto vi Lo finora, in particolare le temati che dei cicli annidati e dello ·viluppo incrementale.

2.2.1

L'istruzione switch/case

Esercizio 2.39 [S] Ri cri vete il frammento di codice dell'e ercizio 2.3 u ando lo switch / case invece dell ' if / else . Esercizio 2.40 [S] È po si bil e ri cri vere il switch / case ? Perché? if

(X >= 0)

Sys tem. ou t. pr intln( "x e ' positivo "); else System . out.println( "x e ' negat i vo ") ;

egu nte

if / else

u ando

lo

2.2 Le strutture di controllo avanza te

2.2.2

27

L'istruzione do /while

Esercizio 2.41 [s] Scri vete, u ando il do /w hile , un prog ram ma e h vi ual izza i nume ri da 1 a IO.

Esercizio 2.42 Scri vete, usando il whil e un programma eh legge da ta ti era un numero intero e visuali zza tutti i numeri da I O fin o a quel numero. Se il numero letto è in fe ri ore a 1O, non vi uali zza null a.

Esercizio 2.43 [S] Mod ifica t l' e rcizio pr cede nte u an do il do /w h ile in vece de l whi le. Atte nzione: e il num ro letto in fe ri ore a IO, non deve visua li zzare null a.

2.2.3

L'istruzione for

E ercizio 2.44 [S] C he cosa fa il programma egu nt ? (ri po ndete enza e egui rlo a l calcolatore!)

class Boh { pu blic static void main (String[J args) { int i; for (i = 1; i < 10 ; i i + 1); System . out. println(i); } }

Perché?

Suggerim ento Leggete molto attentam nt il codice . . .

E ercizio 2.45 Dite cosa succede ·e mod ifica te il programma precedente co ì (ri pondete e nza e eguirl o al calcolatore!): class Boh { pub lic static void main (String[ J args) { for (int i = 1; i < 10; i = i + 1); System . out. println(i); } }

Perché? Veri fica te la vo tra ri po ta compil ando ed e eguendo (anch compil are . . . )

se ba ta

Esercizio 2.46 [S] Scrivete, u ando il f or, un progra mma che visuali zza i numeri da I a I O. Confro ntat lo con i programmi analoghi eh u ano il whil e e il do /w hile , c ritti in precede nza.

Esercizio 2.47 Scrivete, usando il f or , un programma che vi uaJi zza tutti i multipli d i 3 da I a 30.

la programmazione strutturata

28

Esercizio 2.48 [s] Scrivete, u ando il for, un programma che legge da ta tiera un numero intero e vi uaJizza tutti i numeri da IO fino a quel numero. Se il numero letto è inferiore a I O, non vi uaJizza nulla.

Esercizio 2.49 [S] Scrivete, u ando il for , un programma che legge da ta tiera un numero intero e vi uaJi zza tutti i numeri multipli di tre compre i fra quel numero e 100. Se il numero letto è uperiore a I 00, non vi uaJizza nulla.

2.2.4

I for annidati

Esercizio 2.50 [S] Che co a vi uaJi zza il programma

eguente? Ri pondete provando a e eguirlo u carta e poi verificate la vostra ri po ta aJ calcolatore.

class ChiloSa { public static vo i d main(String[] args){ for (int i = 1; i< = 4; i = i+ 1){ for ( int j = 1 ; j (lun ga O); e la i accorc ia ancora di uno, i onien < - (lunga I). O finite il TD Freccia con i metod i per: • accorciare e allungare; •

apere e va ver o destra o ini tra;



apere la lunghezza;

• (*) onenere una nuo a freccia che ia la omma di altre due.

Esercizio 3.102 [s] Scrivet il programma UsoFreccia con un metodo per tampare le frecce e che p rmetta di I. cr are una nuova fr cc ia a lunga 3 ver o de tra;

I metodi e l'occultamento delle informa zioni

62

2. accorciare a fin o a farla e er lunga 3 ma ver o inistra; 3. creare una nuo a frecc ia b di lunghezza e verso letti data ti era ; 4. lampare ogni volta tutte le frecce; 5. lampare il eguente di egno:

1---·---·---> --->--->---> --->--->--->

( e non avete u ato un ciclo avete bagli ato !); 6. (*) tampare il seguente di egno usando una ola frecc ia:

-->-->

1·· --->--->--->

----·----·----·----· ( e non avete u ato un cic lo che modifica la fr cc ia avete bagliato! ).

3.3.5

L'occultamento delle informazioni

Esercizio 3.103 [S] li TDA Ora rappre enta un ' ora del giorno in formato hh: mm. ss , dove hh compre o tra O e 23 , mm e ss tra O e 59. Oltre ad avere un co truttore con tre parametri di tipo byte (uno per le ore, uno per i minuti ed uno per i eco ndi ), ha i metodi : • publ i c static byte getOre ( Ora o) che re titui ce il numero di ore di

o; • public static byte getM i nuti(Ora o) che re titui ce il numero di minuti di o; • public sta tic byte getSecondi ( Ora o) che re titui ce il numero di econdi di o; • publ i c sta tic void aggiungiOre (Ora o, byte h) che aggiunge all 'ora o un num ro di ore pari a h. Allenzione: e l'ora o rappresenta le 22: 32. 12 e i aggiungono 2 ore, il ri ultato arà 0: 32. 12 e non 24: 32. 12; • public stat i c void aggiungiMinuti(Ora o, byte m) che aggiunge all'ora o un numero di minuti pari a m (valgono le te e considerazioni del punto precedente nel ca o i uperi la mezza notte);

3.3 I tipi di dato astrai/i

63

• public static void aggiungiSecondi(Ora o, byte s) che aggiunge a ll 'ora o un numero di secondi pari a s (valgono le te e con iderazioni dei punti precedenti nel ca o i up ri la mezzanotte). Impl ementate il TDA Ora u ando 3 variabili private di tipo byte . nel file Ora. j ava .

aJvate il codice

Esercizio 3.104 [s] Scrivete il programma UsoTDAOra che (non fa te tutto in ieme, ma controllate ogni volta che agg iungete una tampa): I . crei una nuova ora a con i valori letti da ta tiera (ricordatev i he i parametri del co truttore ono di tipo byte e non int);

2 . tampi il valore di a in fom,ato hh: mm. ss ; 3. aggiunga 3 ore ad a e poi ne tampi il vaJore; 4. aggiunga 32 minuti ad a e poi ne tampi il vaJore; 5. aggiunga 12 econdi ad a e poi ne lampi il valore; 6. aggiunga -32 ore ad a e poi ne lampi il valore (è quell o che vi a pettavate?).

Suggerimento Attenzione ai ca t! (a ggiungiOre (a, (byte) 3) e non aggiungiOre(a,3) ).

Esercizio 3.105 [s] Cambiate il codice del TDA Ora dell' e ercizio 3. 103 in modo che, invece di u are 3 variabi li private, u i un array di byte di 3 po izioni ( empre privato). Attenzione: non dovete cambiare I' inte tazione dei metodi e del co truttore. Di più : vi è perme o ricompilare solo il file Ora. j ava , mentre e UsoTDAOra deve funzionare e altamente come faceva prima senza modificarlo né ricompilarlo! Se non lo fa vuol dire che avete sbagliato qua lco a. Esercizio 3.106 [s] Cambiate il codi ce del TD Ora dell ' esercizio 3.103 in modo che, invece di usare un array di byte , usi una ola variabi le i nt (che rappresenta il numero di econdi tra corsi dall a mezzanotte). Ricompil ate so lo il fi le Ora. j ava e controllate che UsoTDAOra funzioni come prima. Esercizio 3.107 (*) Cambiate il codice del TD Ora dell' esercizio 3. 103 in modo che, invece di u are una variabile di tipo int , usi un carattere per le ore ( ' a ' p r l' ora O, ' b ' per l'ora 1, ... , ' n ' per l' ora Il , ' A' per l'ora 12, ' B' p rl ' ora 13, ... , ' N' per l'ora 23) ed una variabiJe di tipo int per i minuti e econdi . Ricompil ate olo il file Ora. j ava e controllate che UsoTDAOra fun zioni come prima.

4

La programmazione orientata agli oggetti

Contenuto 4. I

Dai tipi di dato astratti agli oggetti

4.2

Eredità e polimorfismo

Perché, ad esempio, un gruppo di composti semplici e stabili di carbonio, idrogeno, ossigeno e azoto avrebbe dovuto lottare per miliardi di anni allo scopo di organizzarsi, mettiamo, in un professore [. . . ]? Che cosa li ha spinti? Robert Pirsig

4.1

Dai tipi di dato astratti agli oggetti

Dove si comprende la differenza tra gli approcci procedurale e funzionale e I' approccio a oggetti quando si implementa un tipo di dato astratto, si impara a definire e usare oggetti e si comprende l'uso della parola ri servata this .

4.1.1

Definire e usare oggetti

Esercizio 4.1 [s] Considerate il TDA Coppialnt definito come segue: class Coppiaint { private int x; private int y; public Coppiaint(int primo, int secondo) { x = primo; y = secondo; }

public static int getPrimo(Coppiaint e) { return c . x; }

publ i c static int getSecondo(Coppiaint e) { re t urn c.y;

La programmazione oriemata agli oggeui

66

}

public stat i c void setPrimo(Coppiaint c, int pr imo) { c .x = pr i mo; }

publ ic static vo i d setSecondo (Coppiaint c , int secondo) { c.y = secondo ; } }

Completate (non è detto che al po to di proprio tutti i puntini vada me o qualco a!) la eguente ver ione con approccio a oggetti :

class Ogg ettoCopp i aint pr i vat e i nt x; pr i vate int y; publ i c OggettoCoppiain t (i nt a , i nt b) { X a; y = b;

publ i c i nt getPri mo( ... ) { return x; }

public . . . int getSecondo ( ) { retur n .. . ' vo i d set Primo( . .. pr imo) { x = pri mo; }

public vo i d setSecondo( i nt secondo) { . . . s econdo ;

Esercizio 4.2 [S] Agg iungete all a classe OggettoCoppiaint dell 'e ercizio precedente il metodo (d ' istanza, non di eia se) scambia, che scambi a i valori de lle due componenti tra di loro. Quanti parametri deve avere il metodo scambia nell 'approccio a oggetti ? Esercizio 4.3 [s]

Con ri fe rimento all' eserc izio 4 .1, cri vete il programma UsoOggettoCoppiaint che crea due nuov i oggetti a e b di tipo OggettoCoppiaint con valori letti da ta tiera e po i tampa il primo componente di a e il econdo di b.

Esercizio 4.4 [S] Modi ficate UsoOggettoCoppiaint de ll ' esercizio precedente aggiungendo , a fine programma, la eguente riga di codice:

4. 1 Dai tipi di dato astraili agli oggeui

67

System. out .printl n(Ogge t toCoppial nt . getPr i mo(a)) ;

A pettate a compil are! Vi ono errori ? Perché? Verificate lavo tra ri spo ta provando a compil are. ( on per darv i la oluzione, ma e non vi ono errori avete bagli ato qualco a ... )

Esercizio 4.5 Modificate UsoOggettoCoppiaint dell 'e ercizio precedente aggiungendo, a fi ne programma, la eguente riga di codice: Syst em .out .printl n(Ogg et toCoppi aint . getPr i mo( ));

A pettate a compil are! Vi ono errori ? Perché? Verificate lavo tra ri po ta provando a compilare. (Di nuovo, e non vengono egnalati errori avete bagli ato ... )

Esercizio 4.6 [s] Modificate la clas e OggettoCoppiaint dell 'e ercizio 4. 1 aggiungendo il metodo publi c Stri ng toStr i ng {) che re titui ce una tringa dell a fo rma [ x: y] per rappre entare la coppia con valori x e y. Se ad e empio l' oggetto a cui viene mandato il me aggio toString {) ha le componenti x=12 e y =4, il metodo re tituirà la tringa " [ 12 : 4] ". Esercizio 4.7 [S] Con ri fe rimento al l' e ercizio precedente, modifi cate UsoOggettoCopp i aint dell 'e ercizio 4.5 per far tampare a . on dovete più u are getPr i mo o getSecondo . Dovete u are toStr i ng dell 'e ercizio precedente, ma senza criverlo (o megli o enza criveme l'invocazione) ... Esercizio 4.8 [S] Definite la eia e Portafogli con i metodi • agg i ung i Euro per aggiungere un certo numero di euro al portafogli ; • agg i ung i lire per aggiungere un certo numero di lire al portafogli ; • t ogliEuro per togliere un certo numero di euro dal portafog li (tenete pre ente che non i po ono togliere oldi da un portafogli vuoto!); • toglilire per togliere un certo numero di lire da] portafog li ; • quant i Sold i per apere quanto c'è nel portafog li . La omma re ti tuita deve e ere unica ed e pre sa in euro, anche se nel portafogli ci ono un po' di euro e un po' di lire. • al Verde per apere se non ci ono più oldi nel portafogli . Scegliete attentamente, per ognuno dei metodi , il tipo del ri ultato e il tipo e il numero dei parametri . n euro va.le 1936,27 lire.

La programmazione orier,tata agli oggeui

6

Esercizio 4.9 [S) Con riferimento all'e ercizio precedente, crivete il programma UsoPortafogli che crea un nuovo oggetto x di tipo Portafogli, p r 4 vo lte chiede di in erire da tastiera un num ro di euro da aggiungere al portafogli (non scrivete quattro istruzioni uguali!) , poi chiede di in erire un numero di lire da aggiungere al portafogli , poi per 4 volte chi ede di in erire un numero di lire da togliere al portafogli ed infine chi ede di in erire un numero di euro da togli ere al portafogli . e non al verde tampa ' ' meno male I ' ' e poi , in ogni ca o, tampa il contenuto del p rtafogli.

E ercizio 4.10 [S) Aggiunget a UsoPortafogl i dell' e ercizio precedente un array di n portafogli con n letto da ta tiera. Scrivete un cic lo che, per ogni portafogli , chieda per 7 volte e i vogliono tog li ere o in erir oJdi, e lo i vuol e far in euro o in lire d infine chieda la omma che i vuole in erire o togli er dal portafogli . AlJa fine di tutte le operazioni il programma deve tampare il contenuto di tutti i portafogli. L' output del programma deve e ere imi le a que to:

Quanti portafogli? 2

Portafogli 1 (operazione 1) vuoi aggiungere o togliere (A/T]? A (operazione 1) in lire o euro (L/E]? L (operazione 1) quanto? 121H (operazione 2) vuoi aggiungere o togliere (A/TJ? ... dopo un po ...

(operazione 7) quanto? 3

Portafogli 2 (operazione 1) vuoi aggiungere o togliere [A/TJ? . . . dopo un altro po ' ...

(operazione 7) quanto? 11H Dopo 7 operazioni 11 Portafogli 1 contiene 34,72 euro 11 Portafogli 2 contiene 12,12 euro Esercizio 4.11 [s] De finite il TD Secch i o che rappre enta un contenitor di liquidi che pu contenere olo un numero intero di litri . Il co truttore del TDA ha un unico parametro che de finì ce la capacità de l ecchio. U n ecchio appena cr ato vuoto. I metodi del TDA ono i eguenti :

69

4. 1 Dai tipi di dato astrafli agli oggeui

• riemp i () . Riempie fino all 'orlo il ecchio. Dopo que to m todo il ecchio contiene un numero di litri pari alla ua capacità; • svuota() . vuota completamente il ecchio. Dopo qu to metodo il ecchio contiene un numero di litri pari a zero (i l ecchio uoto); • travasaln ( Secchio s) . vuota il contenuto del ecchio d ntro a un altro ecchio s enza farlo trab ccare. Ad e mpio, e un cchio s 1 di capacità 3 compl etam nte pi no viene tra a ato in un ecchio s2 di capaci tà 4 pie no olo per metà, dopo la chiamata del metodo s1 conterrà I litro e s2 4 litri . e invee s2 fo e tato ini zialmente vuoto, dopo la chi amata del met do, s1 arebb tato vuoto e s2 avrebb cont nuto 3 litri ; • i nt quanto () . Re titui ce il numero di litri contenuti dal ecchio (non la capacità) .

Esercizio 4.12 on ri fe rimento aJI' UsoSecchio eh

ercizio precedente,

I. crei un ecchi o s1 di capac ità IO litri ; 2.

tampi il contenuto di s 1 ;

3. riempia s 1; 4. tampi i] contenuto di s 1 ; 5. crei un ecchi o s2 di capac ità 4 litri ; 6. tampi il contenuto di s2 ; 7 . trava i s1 in s2 ; 8.

tampi il contenuto di s1 e s2 ;

9. trava i s1 in s2 p r la econda volta; I O. tampi il contenuto di s 1 e s2; 11 . vuoti s2 ;

12. trava i s1 in s2 per la terza volta· 13. tampi il contenuto di s1 e s2; 14. vuoti s2; 15. trava i s 1 in s 2 per la quarta volta; 16. tampi il contenuto di s 1 e s2 ;

cri ete il programma

Lo programmazione orientata agli oggett i

70

L' output del programma deve e ere il eguente:

>java UaoSecchio a1 contiene t litri a1 contiene 11 litri a2 contiene t litri a1 contiene 8 litri, 81 contiene 8 litri, a1 contiene 2 litri, a1 contiene t litri,

a2 ne contiene 4 82 ne contiene 4 a2 ne contiene 4 82 ne contiene 2

E ercizio 4.13 [s] (*) Con riferimento ali ' e ercizio 4. 1 l , divertite i a compl etare il eguente codice: class UsoSe cchio { public static void main(Stri ng[J args) { Secchio s1 new Secch i o(5); Secch i o s2 = new Secch i o(3); System .out .println( "s1 contiene "+s 1.quanto( )+" litri "); }

in modo che l' output del programma ia il eguente:

UaoSecchio l>java a1 contiene 4 litri on dovete modificare il TDA Secchio e non devono e erci altre invocazioni dei co truttori . Per ri olver l'e ercizio dovete u are solamente i metodi r i empi, svuota e travasain di s1 e s2.

4.1.2

L'uso di this e della notazione puntata

Esercizio 4.14 [S] Modificate OggettoCoppiaint dell 'e ercizio 4.1 ri cri endo i metodi setPrimo e setSecondo con le inte tazioni eguenti: public void setPrimo(int x) public void setSecondo(int y)

Attenzione: dovete (eventualmente) modificare solo il corpo di que ti due metodi . ient'altro (e quindi , in particolare, u ate e anamente l' inte tazione che vi abbiamo app na dato). Poi modificate, a fine programma, UsoOggettoCoppiaint dell 'e ercizio 4.3 per far modifi care il primo componente di a e il econdo di b con valori letti data tiera e poi far tampare i du oggetti. Funziona tutto come vi a pettavate?

4.1 Dai tipi di dato astrai/i agli oggelli

71

Esercizio 4.15 Modificate OggettoCoppialnt dell'e ercizio precedente cambiando i nomi delle variabili private da x e yin a e b (ovvero cambiate private int x; in private int a; e analogamente per y). Co 'altro deve e ere modifi cato in OggettoCoppialnt per far funzionare tutto come prima, se non si vuole cambiare l 'intestazione dei metodi e del costruttore? Verificate e eguendo di nuovo UsoOggettoCoppialnt . Esercizio 4.16 [S] Aggiungete a OggettoCoppialnt dell ' e ercizio precedente un co truttore enza parametri che, u ando il costruttore con 2 parametri, crea una coppia con entrambi i valori uguali a 1. Modificate poi UsoOggettoCoppialnt per far creare un oggetto c u ando il co truttore appena definito e fate lampare c per controllare eh tutto funzioni come ci i a petta. Esercizio 4.17 [S] La eia e ScacchieraScomoda è un TDA particolare con cui i po ono memori zzare po izioni . Per occupare una ca ella della cacchiera occorre prima lezionarla indicandone la riga con un numero e la colonna con una lettera minu cola e poi u are il metodo metti per occupare la ca ella elezionata. Aggiungete un opportuno co truttore con tre parametri alla eia e ScacchieraScomoda qui di eguito. Il primo parametro dimensione (un intero :::; 26) pecifica la dimen ione della cacchiera, o ia il numero di righe e colonne; il econdo e il terzo, ri pettivamente riga e colonna p cificano la riga (un intero compre o tra l e la dimen ione) e la colonna (una lettera) della cella attualmente elezionata. Alla ucce iva invocazione del metodo metti, la cella elezionata verrà occupata, oppure, e lo era già, verrà tampato a video il me aggio La cella e' gia ' occupata . class ScacchieraScomoda { private boolean[][l dati; private intriga; private int colonna; private static final int DIMENSIONE_MASSIMA = 26; public ScacchieraScomoda(int dimensione, int riga, char colonna) { }

public void metti() { if (dati[riga)[colonna)) System.out.println( "La cella e ' gia ' occupata "); else dati[rigaJ[colonna] = true; }

public String toString() { int dimensione = dati.length;

72

I.A programmazione orientata agli oggetti

String temp = • •; for (int i = 0; i < 2*dimensione +1; i ++ ) temp +=• • • ; temp += "\ n" ; for (int i = 0; i < dimensione; i++) { temp += (dimensione •i

java UaaSeg• entoOrizzontale

••••••

IHIII

Dovete u are solo i metodi dell ' oggetto segmento, ereditati e non.

Esercizio 4.45 [S] (*) Definite la eia e SegmentoVerticale analoga a SegmentoOrizzontale dell'e ercizio 4.43 . Anche in questo caso il metodo toString deve contenere la sola istruzione return disegna(); . Per evitare que ta duplicazione di codice, in quale eia e arebbe tato meglio definire il metodo toString? Verificate la vo tra ri po ta modificando il codice, ricompilando ed eseguendo di nuovo UsaSegmentoOrizzontale dell ' e ercizio 4.44. Esercizio 4.46 [S] Completate il codice eguente (non è detto che tutti punt1ru vadano o tituiti) per far 1 che il programma Interfacce1 stampi 15 e poi 7. interface A { public int m1(); }

B {

public int m2(); interface

e extends ... {

}

class D extends .. . implements ... { public int m1() {return 7;} }

class E implements e { public int m1() {return 3;} public int m2() {return 5;} }

class F { public int m3() {return 1;} }

class Interfacce1 { public static void main(String[] args) { e pippo = new ... ;

84

Lo programmazione orientata agli oggeui

.. . pluto = new D(); prova1(pippo); prova2(pluto); }

public static void prova1( ... x) { System.out.println(x.m1()*x.m2()); }

public static void prova2( .. . x) { System.out.println(x.m1()*x.m3()); } }

Esiste un ' unica oluzione? Verificate tutte le oluzioni che vi sembrano corrette ricompilando ed e eguendo nuovamente il programma.

Esercizio 4.47 [S] Considerate il codice dell'esercizio precedente. Completate il eguente per far stampare 143 al programma I nte rf acce2 scritto qui di eguito . ... G implements A, B { public int m1() {return 11;} }

class H .. . { public int m2() {return 13;} }

class Interfacce2 { public static void main(String[J args) { ... pippo = new ... ; System.out.println(pippo.m1()*pippo.m2()); } }

Esercizio 4.48 [s] Definite l' interfaccia Riproducibile che rappresenta le "co e" che possono essere riprodotte sui regi stratori, lettori di di schi ottici e simili. I metodi dell'interfaccia devono permettere di : • avviare la riproduzione; • fermare la riproduzione; • andare avanti ; • andare indietro.

Esercizio 4.49 [s] Defi nite l'interfaccia Registrabile con i metodi per avviare e fermare la registrazione.

4.2 Eredità e polimorfismo

85

Definite le eia i Video e Audio che implementano le interfacce Riproducibile (dell 'esercizio precedente) e Registrabile con metodi che consistono della sola istruzione System.out . pr i ntln ( ' Sono nel metodo ... de lla classe ... ' ) ;

(sostituite i puntini con il nome del metodo).

Esercizio 4.50 [s] Completate il programma UsaAudioeVideo in modo che: • crei un oggetto Video ; • inizi la riproduzione; • fermi la riproduzione; • vada avanti; • inizi la regi trazione; • fermi la regi trazione; • crei un oggetto Audio e ripeta le tes e operazioni e eguite prima. class Us aAud i oeVi deo { public static voi d main (St ring[J arg s ) { . .. unVi deo = • .. ; prova(unVideo); . .. unAud i o = ... ; prova(unAud i o);

}

Suggerimento Quanti metodi latici prova dovete cri vere?

Esercizio 4.51 (*) Come si può modificare la gerarchia dell 'e ercizio 4.49 per ev itare duplicazione di codice?

4.2.4 Definire gerarchie Gli eserci zi di questo paragrafo sono piutto to lunghi e compl essi. Saper defi nire buone gerarchie è un compito diffic ile per il quale erv irebbe un altro eserciziario. L'obiettivo qui è quello di darv i olo un "a aggio" di quanto c'è ancora da imparare.

La programmazione orientata agli ogge11i

6

E ercizio 4.52 [S] (**) De finite la ei a e I e ia i p r rappre nta r M normali (ma imo 160 caratt ri ) lunghi ( enza limite di aratt ri). Fornite la po ibilità di ottener un array di m aggi normali (qu lii limitati a 160 caratt ri) da un SM lungo, pezzando lo opportunamente (dovete cri vere il metodo spezza () ). Un me agg io de e p rm tt re di impo tare • un d tinatario; • la data e l' ora di partenza ( otto fo rma di St r i ng ); • il mittent . nch in que to ca o do te de finir i metodi e g li attributi opp rtuni. Un me agg io d ve aver un m lodo agg i ung i per aggiung re un carattere . e l ca o degli M normali , qu to m todo de re tituir false non i po ono più aggiungere caratteri . Il met d toStr i ng de e re tituire il me aggio otto fo rma di tringa o ì o me errebb mo trato u un te lefonino con un di pl ay che pu contener al ma imo 25 caratt ri per riga. on dovete mai scrivere due volte lo stes o codi e!

Sugge rimento Pu ervi util e cri vere prima le eia m todi , anche duplicati e po i dec id r la gerarchi a.

on tutti i loro

E ercizio 4.53

ri vete il programma UsaSMS eh vi permetter di in erire data ti era un M normale ed uno lungo e p i li tampa a id o. L' o utput d I programma deve e , ere imi le al eguente ( il te to in erito da ta tiera è quell o in evid nza):

>java UsaSMS Inserisci il tuo nu• ero di telefono: 333123123 Che giorno e' oggi? 31 / 14/2113 Scrivi un • e11aggio breve ( • ax 161 caratteri) Butta la pasta che •to arr1vandol Che ore sono? 12:31 Inserisci il nu• ero di telefono a cui inviare 11 • e11aggio: 348112112 Ora scrivi un • e11aggio lungo Buuuuuuuuuttttttttttttttaaaaaaaaaaaaaaaaaa laaaaaa paaaaaaaa ••••••t•aaaaaaaa ch•••••••• ••••••••••toooooooooooooooo aa•••aa•• rrrrrrrrrrrrrrr111111111111111111vvvvvvvva•••••••••nnnnnnnnnnnnnn ndoooooooooooooooooooooooooooooooollllllllllllll Che ore sono? 12:33 Inserisci il nu• ero di telefono a cui inviare 11 • assaggio: 348114114

4.2 Eredità e polimorfismo

87

Il pri• o ••••aggio, quello breve, e' 11 1eguente: Da: 333123123 A: 348112112 Data: 31/14/2113 12:31

Butta la paata che sto ar rivandol Il ••condo • e11aggio, quello lungo, e' 11 seguente: Da: 333123123 A: 348114114 Data: 31/14/2113 12:33

luuuuuuuuutttttttttttttta aaaaaaaaaaaaaaaaa laaa aaa paaaaaaaaaaaaaaaaa taaaaaaaaa cheeeeeeee asa •••••••toooooooooooooooo aaaaaaaaarrrrrrrrrrrrrrri 11111111111111111vvvvvvvv aaaaaaaaaannnnnnnnnnnnnnn doooooooooooooooooooooooo 0000000011111111111111

Suggerimento

Leggete il me aggio da ta t ie ra con Leggi . unoStr i ng () , poi ricavate un array di char u ando il metodo toCharArray . Ad empio

String x = Legg i .unoString(); cha r[l caratteri = x.toCharArray(); for ( . . .. )

.. . messaggio.aggiung i (caratteri[ i l) .. .

E ercizio 4.54 [s] (**) Defi njte la la e o le e ia i pe r imple menta r un carr Il o de lla pe a in c ui po ono e ere aggiunti o tolti libri o cd. 11 carrell o de e mante nere in un unico array, ini zialme nte vuoto, la li ta de i prodotti aggi unti e do e te impl e m ntar il metodo prodotti () che re titui ce un array contenente tutti i prodotti pre e nti nel carrell o. Impleme ntai anche i metodi o il m todo p r aggiungere e tog lie re libri e cd daJ carre llo . I libri i cd de ono a ere un metodo che re titui ce il loro prezzo. [I pr zzo dev e e re impo tato quando l' oggetto viene c reato.

ercizio 4.55 (*) ggiungete la e ia se che rappr e nta i me agg i voca li ( e nza t sto) a quell e defi nite nell 'e ercizio 4.52. n me agg i vo aie ha un camp by te [] au dio, un d tinatari , il mitte nte e l'ora e data di parte nza. on ha metodi pe r agg iungere e tog li re caratte ri . S iet co tretti a dupli car d I codice vuo l dire c he d vete modificar la gerarc hi a e h a e te defi nito durant l'e rc izio 4.52.

LA programmazione orientata agli oggetti

Esercizio 4.56 Modificate il programma UsaSMS dell'e ercizio 4.53 per fare in modo che i me aggi mo trati all ' utente prima dell'in erimento dei dati da ta tiera (" Inserisc i il tuo numero di telefono: ', "Che giorno e ' oggi? ", "Scrivi un messaggio breve (max 160 caratteri) ", ecc.) vengano critti in dialetto o in un ' altra lingua. Se non riu cite a farlo modificando olo il cod ice di UsaSMS , ma iete co treni a modificare anche quello deg)j SMS, vuol diie che qualco a era tato progettato male. Esercizio 4.57 [s] Con iderate le eia i defin ite nell 'e erc izio 4.54. Implementate la clas e Cassa con un metodo public double conto ( Carrello c) che dato un carrello pieno re titui ce il conto da pagare. Non potete usare i f, swi tch e operatore condizionale. li codice di conto deve e ere irrule al eguente: public double conto(Carrello e) { . .. prodotti = e. prodotti(); for ( . .. prodotti .. . ) { .. . [i l .prezzo(); }

return totale; }

Esercizio 4.58 (*) crivete il programma UsaCarrelloECassa che vi permette di acqui tare 5 prodotti e poi calcola il conto. L' output del programma deve e ere irrule al eguente: >java U1aCarrelloECa11a Quanti libri vuoi acquistare? Inaeriaci il prezzo del libro In1eri1ci il prezzo del libro In1eri1ci 11 prezzo del libro In1eri1ci il prezzo del cd 1: In1eri1ci il prezzo del cd 2: Totale: 82

3 1: 12

2: 11 3: 14 2t 28

)

Java avanzato

Contenuto 5.1

Le API di l ava

5.2

Le interfacce grafiche

na lezione univer itaria un tra ~ rim nt di informazioni dagli appunti d I pr ~ or a quelli de llo tudente enza eh pa ino p r la te la di ne uno de i du . Anonimo

5.1

Le API di Java

Dove i dà un 'occhiata al mondo (qua i terminato!) de ll PI Ja a. U n'anaJ i i esauriente richiederebbe un altro libro, quindi ci i limita ad affrontar i rudimenti della documentazione dell e API Java, delle eccezioni (con le parole ri rvate try, catch, finally, throw, throws) e i ovra crivo n i m todi d Ila e ia Object . L' obiettivo degli e ercizi di que to capito lo, a differenza di quanto fatto finora , non que llo di vi cerare a fo ndo un certo argomento, quanto di far capire aJ lettore che c'è ancora molto da vedere, e fare, per di ventare dei "veri " programmat ri Java.

5.1.1

Le eccezioni

Esercizio 5.1 [s] Considerate la eguente gerarchia di eccezioni : public class EccezionePila extends Exception { public EccezionePi la(String s) {super(s);} class EccezionePilaVuota extends Eccez i onePila { pub lic EccezionePilaVuot a(String s) {super(s);} }

class EccezionePilaPiena extends Ecce zioneP i la {

90

la va avanzato

public EccezionePilaPiena(String s) {super(s);} }

Modificate il seguente codice di Pilalnterilimitata per fare in modo che i metodi metti ed estrai lancino le opportune eccezioni invece di stampare messaggi di errore: public class Pilalnterilimitata { private int[J pila; private int top = 0; public PilainteriLimitata(int max) { this . pila = new int[max]; }

public boolean vuota() {return top pila.length -1;} public int estrai() { if (vuota()) { System.out.println("Errore: la pila e ' vuota "); return - 1; }

return pila[(top -- ) -1); }

public void metti(int x) { if (piena()) { System . out . println( "Errore: la pila e ' piena "); return; }

pila[top++ J

X.

'

}

Esercizio 5.2 [S] Modificate il seguente programma UsaPilalnteriLimi tata per far catturare le eccezioni . li programma (non il TDA) deve stampare messaggi di errore quando cattura le eccezioni: public class UsaPilainteriLimitata { public static void main(String[] args) { PilainteriLimitata pila = new Pilalnterilìmitata(S); for (int i = 0; i b)

System.out.println( "Il mass i mo e ' i l pr i mo "); else System.out.pri ntln( "Il mass i mo e ' i l secondo • );

In que to modo, prima di blo car i in atte a di input daJl'utent , il pr gramma vi uaJi zza un m aggio. L' e ecuzione arebbe:

>javac 1a11l110D1Due.java >java la11inDiDue ln1er11c1 J• due c1tr• d1 cu1 ~uo1 celcolare 1J

N11u,o:

23

Il NIIUIO •• 1J ••condo >

• E ercizio 1.11 La morale che i ricava da que to rcizj (e daJ pr ed nt con iene u are empre l' e ten ion . j ava e aJ are ogni programma in un fil c te o "nome del programma" (q ue l! che c' d po class) a ui aggiung r I ione . j ava . Inoltre , bi ogna pre tare particolare attenzi ne ali I tt r maiu cole, che ono diver da qu Il e minu co le.



6.2 I mattoni di base dei programmi Java 6.2.1

I messaggi d.i errore del compilatore

Esercizio 1.12 o tituendo x con class i hann o i compil atore:

>javac Identificatori.java Identificatori.java:3: nota atate• ent int cla11; Identificatori.java:3: ';' expect1d int cla11; Identificatori.java:3: expected int cla11; Identificatori.java:5: '}' 1xpect1d }

4 1rror1

gu nti me aggi di rr r daJ

112

Soluzioni del capitolo I

Que ti me saggi indicano come il compilatore rimanga piutto to confu o: i rende conto che int class; alla riga 3 corretto (per lui non è neppure un ' i truzione: " not a statement") e poi egnala altri errori che ono cau ati dalla "confu ione" in cui l' abbiamo la ciato. So tituendo x con 1 x i ha una ituazione analoga:

>javac Identificatorl.java Identiflcatorl.java:3: nota 1tatnent int 1x;

.

Identlficatorl.java:3: ' ' expected ' 1nt 1x; 2 errori La differenza daJ ca o precedente è che non compare la parola ri ervata class, che per il compilatore ha un ignificato particolare (e che lo confondeva ulteriormente nel caso precedente). Infine, o tituendo x con x 1 si ha:

>javac Identlficatori.java Identlficatorl.java:3: ';' expected int X 1; 1 error

Qui il compilatore ci dice che i a pettava un punto e virgola dopo il nome di variabile (x). Cercate di familiari zzare con i me aggi di errore del compilatore. A prima vi ta pos ono embrare un po' difficili da comprendere, ma vedrete che po ono e ere molto utili quando criverete i primi programmi "veri ".



6.2.2

I tipi di dato primitivi

Esercizio 1.14 È ufficiente o tituire tutti i tipi int con f loat o con double :

/ * Programma che calcola l ' area di un triangolo*/ class AreaDiUnTriangolo { public static void main (String[] args) { float base; float altezza; float area; base = 4; altezza = 10; area = base* altezza/ 2; System.out.println(area);

6.2 I ma/Ioni di base dei programmi Java

/1 3

• Esercizio 1.15 li prog ramma ri ul tante / * Progr amma per verifica r e mass imi e minimi dei t i pi numeri ci* / class VerificaMassimiMinimi { public stat i c vo i d main (String[J args) { byte b; s hort s ; i nt i ; long l ; b = (byte) ( 127 + 1); s (short)(32767 + 1) ; i (int) (2 147483647 + 1); 1 = (long)(9223372036854775807L

+

1);

Sy stem.out. println( b); System.out.println(s); Syst em. ou t .pri ntl n( i) ; System. ou t. println(l);

e lo i ompi la d

egu , i otti ne:

>java VerificaMa• ai• iMini• i -128 -32788 ·2147483848 -922337213&854775818

Da un valore po itivo (il più g rande po · ibil pe r qu I tip di dato) i pa a, a au a de ll 'ari tm tica circolare de l cal o lator , a un alore negati (il più g rand p ibil e, in va lo re a o luto).



6.2.3

I letterali e le sequenze di escape

Esercizio 1.16 / * Programma per stampare il carattere apice ( ' ) */ class Ap ice { publ ic static void main (String[J args) { char a; a ='\" ;

System.out.print ln(a);

I 14

Soluzioni del capitolo I

6.2.4

Gli operatori fra valori interi

Esercizio 1.19 Le modifiche da apportare aJ programma AreaDiUnTriangolo ono: • uso della variabile h al posto di altezza ; • u o di due variabi li b1 e b2 (per base minore e ba e maggiore) al posto di base ; • a egnamento di un valore iniziale a tutte le variabili precedenti ; • modifica de ll ' e pre ione con la formula per il calcolo dell ' area. Il ri ultato è:

class AreaDi UnTrape zio public static void main (String[J args) { int b1 ; int b2 ; int hj int area; b1 = 5; b2 = 10; h = 12; area = (b1 + b2) * h / 2; System.out.println(area); }

Le parentes i nell ' e press ione ono necessarie per far e eguire la omma prima dell a moltiplicazione.



6.2.5

L'operatore di modulo ''%"

Esercizio 1.23 I valori vi suali zzati sono 8 ( 16 di vi o due), 7 ( 15 diviso 2, con la di visione intera, fa 7 con re Lo I ), 0 (il resto de ll a divi sione di 16 per 2) e 1 (il resto della di visione di 15 per 2) . Il programma per verificare la ri po ta è il seguente: class Valor i DiX { publ ic static void ma i n (String[J arg s) { int Xj X =

16 / 2j

System.out .println(x); X = 15 /

2j

System . out . pr i ntln(x); X =

16 % 2j

Syst em.o ut.pr intln (x) ; X = 15 % 2;

System. out.println (x); }

}

6.2 I ma11011i d i base dei programmi l ava

115

Compilando ed e eguendo il programma . i otti ene:

>javac ValoriDiX.java >java ValoriDiX 8 7

• 1



Esercizio 1.24 Generalizzando le ultime due espre ·ioni aritmetiche del programma precedente, si osserva che la divisione per du di un numero pari dà r to zero que ll a di un numero dispari dà re to uno. Ma que to proprio ci he ci erve: di vidiarn x per due e ne prendiamo il re to (con l'operatore di modulo%), otteniamo il valor da a · egnare a y. Quindi l' e pre sione cercata è x % 2 e il programma va ompletato così : cl ass Pa r i Dis par i { public static void main (St r i ng [J args) { i nt y; i nt x; X = 17; y = X \ 2;

Sy stem.out.pri ntln(y); }

A egnando a x un valore, ricompil ando ogni volta ed e eg uendo i otterrà in output 0 e il valore a egnato a x è pari e 1 e è di pari. Ad e empio, compil ando d

e eguendo il programma precedente i ottiene:

>javac PariDiapari.java >java PariDiapari 1

È nece ario ricompil are perché per as egnare un valore a x i de e modi ficare il orgente Java.



6.2.6

Il tipo di dato boolean

Esercizio 1.25 Que llo che ci erve è un ' e pre sione che as urna un va lore booleano (quindi true o false ) a econda che x ia pari o di pari. Abbiamo vi ·to nell ' e ercizio precedente che l' e pre sione x % 2 va le zero e x è pari , uno e x è di pari, e que ti ono gli unici due valori po ibili . Ma aJl ora basta trovare il modo di ottenere true e una certa e pre ione (nel nostro ca o x % 2) è uguale a zero e f alse e quell ' e pre ione è uguale a uno. E questo si può fare con l' operatore==, da u are

Soluzioni del capitolo 1

116

per chieder i e la no tra e pre ione è zero. L e pre ione che ci erve è quindi ( x == 0. Quindi l' i tru zione di a egnamento cercata è: p = ( (x % 2) == 0) (in realtà, le parente i ono tutt no n n ce ari p rché la priorità de ll'operatore di modul o% è uperi re a que ll a de ll 'operatore di confronto == la qual e a ua volta uperiore a quell a dell 'operatore di a egnamento =) e il programma per verificare la ri spo ta

% 2)

class Pa r i Dis par i Boolea n { public st at ic void main(Strin g[ J args) { boo lean p; i nt x; X = 17; p = X % 2 == 0 ; System . out .p rintln( p) ; } }

Compil ando ed e eguendo i ottiene:

>javac PariDispariBoolean.java >java PariDispariBoolean false Vedi amo alcune oluzioni al ternati ve ma pegg iori. Prima di leggere la oluzio ne corretta, alcuni di voi avranno pen ato, ad e empio, a:

p = (x % 2 == 0) == t r ue; Que La i truzione ottiene l' effetto voluto, ma è pegg iore di quell a propo ta. Qui l' error con i te ne l confrontar un valore booleano con t rue (ma arebbe lo te so con false ). Que to va sempre evitato perché /a eseguire un 'operazione in più al cal olatore! E que to error an he empi ice da vitare: ba ta ostituire istematicamente nei vo tri programmj

E == true con E

E

false

con IE

(no t E). Itri di vo i avran no pen ato di usare l' operatore condizionale" ?: " per assegnare a p il vaJ or cercato :

6.2 I mattoni di base dei programmi l ava

p

= (x

%2

==

11 7

0) ? true : false;

Anche questa i truzione ottiene l' effetto voluto ma, ri petto alla oluzione migliore, meno elegante e meno effi ciente. Un programmatore profe ioni sta non farebbe mai co ì. In realtà, anche questo errore è emplice da evitare: ba ta veri ficare che nei vo tri programmi non compaia mai un'e pre ione del tipo E? true : f alse

dove, aJ po to di E c'è un 'e pre ione booleana qual iasi. Se l' e pre ione pr cedente compare nel vo tro programma, affrettatev i a o titu irla con E

prima che il prof. e ne accorga ... Se poi avete addiri ttura critto p

= (x

%2

==

0)

==

true? true : false ;

all ora iete riu citi a commettere entrambi gli errori precedenti ...



Esercizio 1.26 Qui l' espre ione cercata molto imi le a quella dell 'e ercizio precedente. Invece di veri ficare e il modulo dell a divi ione per 2 zero, bi ogna emplicemente verificare e x è maggiore di (o uguale a) zero, o ia: x >= 0 . Quindi I' i truzione cercata è p = ( x >= 0) (le parente i ono uperflue) e il programma (da compilare ed e eguire per più valori di x) è: cl ass Positivo { public st atic voi d mai n(Stri ng[] args) { bool ea n p; i nt x; X = - 12 ;

p

= X> =

0;

System .o ut .println( p);

Compilando ed e eguendo si ottiene:

>javac Poaitivo.java >java Positivo falH



Esercizio 1.27 li vaJore da a egnare a p è ottenuto come or logico delle espre sioni trovate nei due esercizi precedenti: x >= 0 per capire se x è po iùvo e x % 2 == 0 per capire e x è pari . La ri po ta è quindi p = ( x >= 0) : : ( x % 2 == 0) . Le parente i non ono indi pen abili, ma in que to ca o aiutano perché l' e pre ione comincia a e ere meno banaJe delle precedenti . li programma per veri ficare la correttezza del la no tra ri po ta è:

11 8

Solu zioni del capitolo 1

class Pos itivoOPar i { public static void main(String[J args) { boolean p; i nt x; X = - 12; p = (X >= 0)

: : (X \ 2

0);

System.out.println(p); }

E la ua e ec uzione (dopo, ovviamente, la compilazione) è:

>java PoaitivoOPari l_true Invece de ll ' operatore " : : " i sarebbe potuto u are l' a ltro operatore di or logico ' : " , e il ri ultato arebbe tato lo ste so. La prima oluzione è leggermente preferi bile p r que tioru di efficienza, in quanto ri parrruamo aJl ' inte rprete Java la fatica (rru nima, in verità .. . ) di vaJ utare I' e pre ione x % 2 == 0 quando I' e pre ione ( x >= 0) è

true . Le oluzioni che u ano l'operatore condizionaJe " ? :" perco truire e pre ioru più o r:pe no compie e pe r ottenere lo te ori ultato o no meno e leganti ed efficienti .



Esercizio 1.28 Leggendo attentamente il te to dell ' e ercizio, i nota che l'unica diffe re nza daJl ' esercizio precedente è la congiunzione "e" al posto della "o". Lari posta arà quindi molto irrul e aJla precede nte: p = ( x >= 0) && ( x % 2 == 0) . E anche il programma non è mo lto di ver o :

class Pos itiv oEPar i { public static vo i d main( St r ing[J args ) { bool ean p; i nt x; = - 12 ; p = (X >= 0)

X

&&

(X \

2 -- 0) ;

System.out.println(p); } }

E l' e ecuzione dà:

>java PoaitivoEPari l_falH Anche qui , l' u o di "&&" invece di"&" è leggermente preferibile.



Esercizio 1.29 Dobbiamo criv re un 'e pre ione b oleana vera (cioè un 'e pre ion che viene valutata a true) nel ca o in cui x appartenga a uno dei tre intervaJ Li . Incorrunciamo daJ vedere come contro ll are se una variabil e ha un vaJore compre o

6.2 I mattoni di base dei programmi l ava

11 9

in un interva llo; per fi are le idee, lavori amo u x e ul primo intervallo di que to e ercizio, [ 15, 18]. La inta i Java non ci con ente di cri ere e pre ioni come 15 = 15. Que to pu mbrare trano, in quanto appiamo di poter criv re co e come x + y + z (dove x, y z o no, ad e empio, di tipo i nt ). Ma i due ca i ono di r i: vedi am o di capire perché. Quando criviarno x + y + z in r aJ tà intendiamo (u ando la propri età a oc iativa dell a omma) ( x + y) + z . In fa ni l'interprete Java e egue prima la omma x + y e ne memori zza il ri ultato in una variabil e tempo ranea il cui ala re iene poi ommato a z p r ottener il ri ultato dell ' e pre ione. otiamo che la ari abile temp ranea di tipo i nt , e quindi la econda operazio ne di omma è una no rmali im a omma fra due tipi i nt . Di ver o il ca o di 15 java Trucchi 1

• • E ercizio 1.36 Ricordi amo innanz itutto c he l' operatore m dul o d

il r to d Il a

di vi io ne int ra. Ve niamo ra aJ l'e e rcizio . Il suggerim nto c i dà, di fatto , la o lu zi ne: ci i n detto di " a · egna re a y il modul 2 d ll 'e pr ione x + 1" , o ia, in Ja a y = (X + 1) % 2;

Vedi amo di capire perc h fun ziona. Po iarno ederlo in du m di : • L'i truzione a egna a y il val or ucc ivo al va lore di x ma ' riman ndo confinati " (grazie al modulo 2) fra 0 e 1 , h ono gli uni ci va lori c he pu a umere il re to de ll a divi ione pe r due. Quindi , il " val or " di 0 1 il " a lor u ce i o" di 1 0 (perc h due "u cirebbe dai onfini" quindi " i ricomincia daccapo"). • C i on due po ibilità : e x aie 0 , allora l' e pre ione all a de tra dell 'a egnam ento va le (0 + 1) % 2, ia 1 % 2 , os ia 1 (uno di i due fa z ro con re to un ); se x val 1, allora l'espre ion e al la de tra dell' a gname nto va le ( 1 + 1) % 2 , o ia 2 % 2 , o sia 0 (due di i o due fa uno con re to zero). Il br ve pr grarruna di verifica cede nte).

la c iato al lettore ( analogo al programma pr -

• Esercizio 1.37 Dopo aver fatto fatica per trovare o luzioni corrette ma brutte, rip niamo al probl e ma ·egue ndo il uggerimento. Ci ono i o liti due ca i: e x vale 0, y va le 1 e e x vale 1, y vale 0 . Quindi , x + y vale empre 1 . Ma aJlora abbiamo I'equaz ione x + y = 1, c he po iam ri crivere come y = 1 - x . Eque ta equazione può e e re immediatamente tra formata nell'i truzione

Solu zioni del capitolo 1

124

y = 1 - x;

O ervate che il imbolo " =" nell e ri ghe precedenti ha due ignifì cati : in termini matematici indica l' uguaglianza, mentre ne l codice Java ignifica piutto to "diventa" (ad e empio, l'ultima i tru zione può e ere letta come " y diventa 1 meno x"). libre e programma di verifica è empre anaJogo ai precedenti . Que ta oluzione mi gliore dell e pr cedenti perché: • è più emplice, da to che le precedenti i ba ano u ragionamenti più lunghi e complicati e u ano operatori de l linguaggio non nece ari (' ? : " e "%" );



più elegante, grazie aJla ua emplicità. Queste due prime motivazioni po ono e ere diffi cili da percepire per chi non ha una ' en ibilità' matematica: un buon motivo p r non nobbare gli in egnamenti matematici ... Comunque ricordate che " emplice è bello";

• e endo più emplice, anche più efficiente, dato che l'operazion di ottrazione viene e eguita piu velocemente de ll e operazioni precedenti . In que to ca o il vantaggio veramente minimo, ma e I ope razione in que Lione fo e rip tu ta mi gliaia o mili oni di volte, come potrebbe e ere in un programma reale, la differenza arebbe chiaram ente percepibile.

• Esercizio 1.38 Il valore a oluto di un numero x è: • uguaJ e a x e x

po itivo;

• uguaJe a - x e x è negativo. In Java, con l'operatore condi zional e, po iam o crivere la empli ce i truzione eguente, che a segna a y il va.lore a oluto di x: y = X >= 0 7 X :

· X;

Altre oluzioni ono: y = X > 0 7 X :

-x;

y

X < 0 7 · X : x;

y

X< = 0 7 · X :

x;



Esercizio 1.39 Se l'intermezzo ul valore a oluto vi ha di tratto, il uggeri mento vi ha riportato ulla retta via. Ba tari-analizzare l'i truzione y = 1 - x;

125

6.3 Tecniche, problemi e trucchi ricorrenti

dell' e er izio 1.37 e o ervare c he qui iamo in una ituazione analoga, con l'unica differenza che ' un ' uni ca variabile (turno ) anzi e h due (x y), e c he turno lge il ruolo di e ntrambe: va u ato nell a pa rte de tra d ll 'a egnam nto p r ca l o lare il nuo o va lor , e a u al nell a parte ini tra dell 'a egname nt p r a ume r il nuo o valore. Quindi lari p ta (mig liore)

turno =

1 -

turno;

L'u o di una ulte riore variab ile, com in

int temp; temp = 1 - turno; t urno = temp; up rfluo e porta a una o luzi n me no ffi i nte ed el gant . In fa tti , n n han en o fare un pa o " int rm dio" h in r altà non int rm dio p r ni nt . .. ( in più! ) Sp ndi arno due rig he anc he p r g li in rreggibili che av e ro ri

t urno = turno == 0

? 1 : 0;

o turno = (turno +

1) \ 2;

o a d ire, s non e h siete "caldamente" in itali a ri ede r i con più o luzioni precedenti ??

E ercizio 1.40 In qu to ca o lo tralag mma adottato n I ca o pr

tt nzi n I



de nt n n fun z iona (pro are per cr d re ... ). Pe r non dim ntic hi a mo id Il luzioni alt rnati Que ta vo lta, come ci indica il uggerimento, l' op rat r di m dul proprio qu Il c he c i erve, iccome ci on ente di "tenere confin ati " i alori di turno fra 0 e 3 . L' i truzion compl eta da in e ri re nel programma

turno = (turn o+

1) \ 4;

Vedi a mo pe rc h fun ziona. Questo as egnamento fa ì c he: •

e turno vale 0, e o diventa 1 (0 + 1 );



e turno va le 1, e ·o div nta 2 (1 + 1 );



e turno vale 2,e od iventa3(2 + 1);



e turno vaJe 3 , es o dive nta 0 (3 + 1 % 4 aie 4 % 4 o ia 0). gui a mo il programma otteniamo:

>java Turno Giro nu• ero I Ora e' di turno giocatore I Giro nu• ero 1 Ora e' di turno giocatore 1 Giro nu• ero 2 Ora e' di turno giocatore 2

Solu zioni del capitolo I

126

Giro nu• ero 3 Ora e' di turno giocatore 3 Giro nu• ero 4 Ora e' di turno giocatore Giro nu• ero 5 Ora e' di turno giocatore 1 .. . ecc. ecc. Giro nu• ero 17 Ora e' di turno giocatore 1 Giro nu• ero 18 Ora e' di turno giocatore 2 Giro nu• ero 19 Ora e' di turno giocatore 3 Giro nu• ero 21 Ora e' di turno giocatore





O erv iamo c he i ar bbe potuto c rivere un programma con comportame nto analogo fruttando la variabi le i , ma co ì face ndo non avr mmo ri olto l'e ercizio, che c i chi edeva espli citam nte di crivere "l'i truzio ne di a g namento che a egna di vo lta in volta a turno il valore corretto ulla ba e del valore precedente."



Esercizio 1.41 turno = (turno + 1) % 7;

E ercizio 1.42

egui a mo il suggerime nto e parti amo da ll a

• o luzione dc li '

cre i-

zio 1.40, o ia

turno = (turno + 1) % 4 ; e inve rtiamo l'ordine di " +" e "%", ottenendo:

turno = turno % 4 + 1; Co ì facendo , dapprima t urno viene "confinato ' fra 0 e 3 dall ' operatore "%' poi al valore co 1 ottenuto vie ne aggi unt 1 . Que ta istru zione fa proprio qu Ilo c he ci erve, ma e la in e riamo ne l codi ce o tte nia mo

class Turno { publ ic static void main(String[ ] args) { i nt turno; int i ; turno = 0; i = 0; while (ijava Turno Giro nu• ero I Ora e' di turno giocatore I Giro nu• ero 1 Ora e' di turno giocatore 1

127

6.3 Tecniche, problemi e trucchi ricorrenti

Giro Giro Giro Giro Giro

...

nu• ero 2 Ora e' di nu• ero 3 Ora e' di nu• ero 4 Ora e' di nu• ero 5 Ora e' di nu• ero 8 Ora e' di (e altri eli• inati)

turno turno turno turno turno

giocatore giocatore giocatore giocatore giocatore

2 3 4

1 2

Quindi in que to modo otteniamo la equenza di valori O, I, 2, 3, 4, I, 2, , 4, . . . i manca ancora una piccola modifica, perch il primo valor (0 ) non qu Il v luto. Co me ci dice il uggerimento, ba ta modificare il valore iniziaJ di turno , da 0 a 1, ottenendo la oluzione corretta:

class Turno { public static void main(String[J args) { int turno; i nt i; turno = 1; //E ra ze ro i = 0; while (i java Prova Exception in thread •• ain" java.lang.NoSuchlethodError: • ain >

Que to me saggio è meno compren ibil e dei precedenti , ma con un po' di sforzo capi amo che l'interprete (non il compilatore !) Java ci ta dicendo che non trova il

135

7.1 Le strullttre di contro/lo di ba e

metodo main (" . . . quinto errore :

NoSuchMethodError:

main "). E infatti ha rag io n lui ! Il

• Main anzich ma i n (le lett re maiu cole ono diver e daJle minu e I e gni pr gramma de e avere il " main").

orr ggendo anche que to, salvando, ricompilando e rie eguendo on niam

>javac Prova.java >java Prova X •

1

y •

2

z • 3 enza più errori .

Esercizio 2.2

ome abbiamo appe na vi to, il pr gramma



class Prova { publ ic static vo i d main(String(] args) { int Xj int y; int z ; X

y y Z

= 1 '.



= X ' + 1. = y + Xj'

System.out . pr intln( "x



+

x + "\ ny = • + y + "\ nz = • + z);

} }

vi uaJi zza

>javac Prova.java >java Prova X •

1

y • 2 z • 3

Invertendo l'ordine delle ultime due i truzioni di a egnamento i aJori i uaJizzati potrebbero essere diver i (perché, anche e vengono e eguite le te e i truzioni quete vengono e eguite in un ordine diver o) . Per capire che vaJori dobbiamo a pettarci, ba tao ervare che ubito prima dell 'e ecuzione de l primo dei due as egnamenti x vaJe 1 e y vaJe 2. e e eguiamo prima, come ci viene chie to, z = y + x; , a que to punto z vaJe 3 (e x e y ono invariate). E eguendo po i y = x + 1 ; , y a urne il vaJore 2. I vaJori vi uaJi zzati ono quindi invariati e ono I, 2 e 3, come i pu verificare modificando il programma

136

oluzioni del capitolo 2

class Prov a { pub lic static voi d main(String [J args ) { i nt x; i nt y; i nt z ; X =

1;

y 2; z = y + x; y X + 1;

System.out.p rint ln ( "x

'+ X +

'\ ny

' + y + ' \ nz

' + z) ;

}

ed e eguendolo (dopo aver ricompil ato!):

>javac Prova.java >java Prova X • 1 y • 2 z • 3

Per quanto riguarda l'ul ti ma domanda, la ituazione embra analoga. Ma non lo è. Infatti , cambiando l' ordine di y = 2; e z = y + x; uccede che, ovv iamente, viene e eguito prima z = y + x; . Ma nell 'e pre ione aJla destra di que lo a egnamento (y + x) compare una variabile (y) che ancora non ha un valore! E in fatti , il compilatore egnala un errore:

>javac Prova.java Prova.java:I: variable Z •

J +

y

• ight not have been initialized

Xj

1 error

• 7.1.2

L'istruzione di selezione i f / else

Esercizio 2.3 L' output del programma è invariato. Per capire il perché, o ervate che le quattro condi zioni dei quattro i f ono in alternativa: e una di e e vale true , le altre valgono false . Ma i veda l' e ercizio eguente. ..



Esercizio 2.4 Eliminando gli else co tringiamo l' interprete Java a confro ntare x con tutti i valori (0, 1, 2 e 3), mentre quando si ha, ad e empio, che x vale 0 è inuti le precare tempo a effettuare i tre confronti succes ivi . Inoltre, da un punto di vi ta logico, è pi ù en ato pensare a que to fra mmento di programma come " e x val e 0,

7.1 Le srru1111re di controllo di base

137

al lora . . . , altrimenti ex vale 1 ecc.": i 4 valori ono in alternativa. Infine, pro ate a pen are a co a uccederebbe e invece di avere 4 confronti ne ave imo I 00...



bbiarno già i to più olte come l' e pre ion n % 2 == 0 ia true pari e false aJtrimenti. Quindi , enza troppa fatica , po iarno cri er :

Esercizio 2.6 en

if(n % 2 == 0)



System.out.println( "Ciaol " );

Esercizio 2.7 Anche qui lari po ta

emplice:

if(b)

System.out . pr i ntln( ' Ciaol " ); Se avete u ato l' op ratore di uguaglianza incorreggibi li . . .

==

(in if ( b -- tr ue) ), iet proprio



Esercizio 2.8



y = ( X >= 0) ? y + 1 : y + 2;

Esercizio 2.9 La diffico ltà con i te nel fatto eh

e la condizione ( x >= 0 ) il valore di y non deve variare. Ma allora ba ta u are y te ' O:

false ,

y = ( X >= 0) ? y + 1 : y;



Esercizio 2.10 if (X>= 0 && X % 2 z = 0;

1)

else z = 1;

Esercizio 2.11 Seguiamo il uggerimento e ri criviamo il codic u. ando du i f :



if (x >= 0 ) y = y + 1· if (X < 0) ' z = z + 1.

'

iccome i due i f ono in mutua esclu ione (uno o lo dei due è vero) abbiamo un programma equivalente a quello dato. Ora app licando lo te o procediment dell 'e ercizio 2.9, abbiamo: y = ( X >= 0) ? y + 1 : y; = (X < 0) ? Z + 1 : z;

Z



138

Soluzioni del capitolo 2

7.1.3

Gli i f / else annidati

Esercizio 2.14 Se siamo proprio costretti a usare degli i f pos iamo scrivere: class AliceEBob { public stat i c void ma i n(String[J args) { boolean terrari; boolean mocassini; boolean occhialiOaSole; boolean uscita = false; System.out.print( "Bob e ' in Ferrari? (true/false) " ); terrari = Leggi.unBoolean(); System.out.print( "Bob ha i mocassini? (true / false) ' ) ; mocassin i = Leggi.unBoolean(); System.out.print( "Bob ha gli occhiali da sole? (true / false) ' ); occhialiDaSole = Leggi.unBoolean(); if(ferrari) { if( I mocassini) uscita = true; } else if (locchialiDaSole) uscita = true; System . out . println(uscita? ' Usciamo ... " : ' Non usciamo . "); }

Come abbiamo già discusso in abbondanza nel capitolo precedente, si può però scrivere del codice migliore. Un primo miglioramento è l' eliminazione degli i f interni : if(ferrari) usc i ta I mocassini; else usc i ta locchialiDaSole;

(il resto rimane invariato). semplicemente con:

O, ancora meglio, possiamo eliminare tulli gli i f

uscita = (ferrari && !mocassini) : : (lferrar i && locchial i DaSole);



Esercizio 2.16 La soluzione è (per convincersene, può e sere utile disegnare il diagramma di flu so del frammento di programma dato): if

(IX)

System.out . println( ' Boh ' ) ; else if ( ly) System.out . println( "Mah ' ); else if (z) System.out.println( ' Si, si, si ' );

7. I le strutture di controllo di base

else System.out.println( "Si, si, no ");

7.1.4

/ 39



L'istruzione while

Esercizio 2.17 class While { public static void main (String[) args) { int i; i = 10;

while (i x) break; System .o ut . pr intln( " ( ' + (n - 1) + " • + x

+ ' ) ' );

Esercizio 2.65



class Ou adrato1 { public stat i c void main (String[J args) { for (int i= 1; i< = 8 ; i++) { for ( i nt j = 1 ; j = 1; c -- ) // cifre decrescenti System . out . pri nt (c ); System.out.pri ntln(); }



7.3 Gli array

7 .3

157

Gli array

7.3.1

Array unidimensionali

Esercizio 2.81 Una oluzione possibile è la eguente: class Di eciDouble { public stat ic void ma i n (String[I args) { double[I a; a = new double[10J; for (i nt i = 0; i< a.length; i++) { System.out.pri nt( "Inserisci il•+ (i+ 1) + "o valore: "); a[i) = Legg i. unDouble(); }

for (i nt i = 0; i< a . length; i++) System.out.pri ntln( ' Il • + (i + 1) + ' o valore letto era: • + a[ i l); }

otate come si " pazzolano" tutti gli elementi di un array con un ciclo for. Le intestazioni dei due for nel programma ono identiche, e potrebbero e ere o tituite da for (int i = 0; i javac U10Coppialnt.java u,ocoppialnt.java:8: cannot re,olve 1y• bol 1y• bol : • ethod getlecondo (Coppialnt) location: cla11 U10Coppialnt Sy1te• .out.println("Que1to •• il 1econdo co• ponente della coppia: • + getlecondo(a));

1 error

• Per creare una coppi a b i u ano le te e i truzioni u ate per creare a .

8.3 I tipi di dato astratti

195

• Per creare x con il prim component di a d il econdo di b i potr bb I. mettere il primo componente di a in una ariabile temporanea (i nt t1 = Coppialnt . getPrimo(a); ) 2. m nere il condo componente di b in un ' aJtra ariabi l t mp ranea (i nt t2 = Coppialnt . getSecondo(b); ) 3. creare la nuo a coppia (Coppialnt x = new Coppialnt(t1,t2); ) t p r che le funzioni po n le variabili t1 e t2 non rvono da n ·crivere una ola ri ga di codice

re u at com fo ero vaJori eh un ' altra parte, i pu (m gli o, i deve)

Coppialnt x = new Coppiaint(Co pp i aint.getPri mo(a), Copp i aint.getSecondo(b)); • Per creare una coppia e con due numeri letti data tiera u iamo il metodo un I nt de ll a eia e Leggi. Come prima p tremrn I. leggere il primo numero e meli rio in una ari abil e temporan a (int t1 = Leggi.unlnt(); ) 2. leggere il econd numero e metterlo in un ' aJtra (i nt t2 = Leggi.unlnt(); )

ariabile temp ranea

3. cr are la nuova coppi a (Coppialnt e = new Coppialnt(t1,t2);) per gli t dobbiamo!)

moti i di prim a p iamo ( e vogli amo riv re una o la ri ga

ri ere b ne il codice

Copp iaint e = new Copp i aint(Leggi.unint(), Legg i. un I nt ()); • Per " opiare" il primo componente di e nel econdo di a potremmo I. mettere il aJore de l primo componente di e in una variabi le temporanea (int t1 = Copp ialnt . getPrimo (e); ); 2. m dificare il econdo componente di a con il contenuto de ll a variabile temporanea (Coppiaint . setSecondo (a, t 1 ) ; ). Anche in que to ca o è megli fare tutt con una ola riga di codic Coppi aint.setSecondo(a, Copp iaint. getPr imo(c )); otate che è invece bag liato criver : Copp i aint.getSecondo(a) = Copp i aint . getPr imo(c);

196

Soluzioni del capitolo 3

Infatti , i potrebbe pen are che que lo codice ia l' equival ente di

a.y = c.x; invece il metodo getSecondo re tituisce olo il vaJore numerico e quindi il codice di prima è semmai equivaJente a 56 = 7;

(suppo to che e abbia 7 come primo componente e a 56 come econdo). Gli altri punti corri pondono a emplici u i dei metod i de l TD



Esercizio 3~83 fl codice di stampaCopp ia int è : public static void stampaCoppialnt(Coppiaint e) { System. out . print ( " [ "); Sys tem .out.pri nt (Copp ial nt.getPr imo(c)); System.out . print( ":" ); System.out.pri nt( Copp iaint.getSeco ndo(c) ); System.out.println ( " ] ' ); }

oppure, con una ola riga di codice

publ ic static vo i d stampaCoppiaint(Coppiaint e) { System .out . pri ntln( ' [ ' + Coppia lnt.getPrimo(c) + • : •+ Copp ialnt .ge tsecon do (c) + "] " ); }

otate che non è po ibile fare riferimento alle componenti della coppia con e. x e e. y perché il metodo stampaCoppiaint è all'interno di UsoCopp i aint e non in Coppialnt .



Esercizio 3.85 Per stampare un rettango lo di a teri chi i può, u ando un metodo iterativo, fare co l: publ ic static vo i d stampaRettangolo( Copp ia in t e) { f or (int i = 0; i< Coppia lnt.getP rimo (c); i++) { for (int j = 0; j < Copp iaint .getSecondo (c); j++) System.out.pr i nt( "*' ) ; System.out.print ln( ); }

• Esercizio 3.86 Per stampare il rettangolo inver o è uffic iente I . cambiare le componenti della coppi a con il metodo scambiaElementi 2. chi amare stampaRettangolo potrebbe sembrare che sia finita qui , invece è importante ricordar i di cambiare di nuovo gli elementi dell a coppia. Immaginate infatti di aver scritto que to codice:

8.3 I 1ipi di da /o a 1rat1i

/ 97

Copp ia lnt a = new Coppialnt(2,3); Syst em .out.print ln( ' Il pri mo eleme nto di a e ' • + Coppiaint.getPrimo()); stampaRettangoloinverso(a); System. out.pri nt l n( "Il pr i mo eleme nto di a e ' sempre • + Copp ia int.getP rimo());

L'output che ci i a petta è

Il prillo ele• ento di a•• 2 ** ** **

Il pri• o ele• ento di a•• 1eapre 2 e invece, se non cambiamo due volle gli elementi di a, otteniamo

Il pri• o ele• ento di a•• 2 ** ** **

Il prillo ele• ento di a•• •NPr• 3

li codice di stampaRettangoloinverso è dunque: publ ic static vo i d stampaRettangololnverso(Coppialnt e ) { Coppialnt . scambia Elementi(c); stampaRettangolo(c); Coppialnt .scamb iaEl ement i(c); }

.

Esercizio 3.87 Il codice di stampaRettangoloConPunto è praticamente lo te so di stampaRettangolo: va modificata olo l' i truzione che tampa il imbolo. Se la ri ga e la colonna corri pondono alle componenti della seconda coppia pa ata come parametro (decrementate di 1 perché i e j partono da O e non da 1), aJlora tampa o, altrimenti stampa •. publ ic stat ic vo i d stampaRettangoloConPunto(Coppia lnt e, Copp ia lnt a) { for (i nt i = 0; i < Coppi aint . getPrimo(c); i++) { for (int j = 0; j < Coppi aint.getSecondo(c); j++ ) i f (Coppialnt . getPrimo(a) -1 == i && Coppiaint.getSecondo(a) -1 == j) System . out.print( "o ' ); else System.out.print("* ' ); System.out . pr i ntln(); } }



198

o/uzioni del capitolo 3

8.3.2

Metodi in versione procedurale e funzionale

Esercizio 3.88 Chi am eremo il metodo eh

azzera la prima componente a zz eraPr i mo (che fanta ia, vero?). Come uni co parametro avrà una coppia. Il codice in ver ione procedurale è il eguente: pu blic static void azzera Pr imo (Copp ia l nt e) {

c .x

= 0;

}

in ver ione funzionale lo potremmo crivere co ì (le di ffe renze o no videnziate): public static Coppialnt azze r aPr imo (Copp ial nt e ) {

c.x = 0; return e; }



Esercizio 3.89 Ba ta aggiungere la chi amata al metodo defi nito nell a oluzione pr cedente pa andogli come parametro attuale b: Copp ial nt. azze r aPr imo(b ); Se il codice di a z zeraPr i mo anche co ì: b

=

tato critto in modo funzionale, po iamo cri vere

Copp ialnt.azzeraPrimo(b );

Se invece nell a o luzione dell ' ercizio prec de nte abbiamo celto la ver ione pro eduraJe, quest' ultima soluzione non va bene.

• Esercizio 3.90 Per azzerare il econdo componente di b enza u are se t Secondo e senza aggiungere metodi a Copp i alnt , ba ta agg iungere all a fi ne del ma i n di UsoCopp i aint le ri ghe Coppia lnt . sc ambiaEleme nti( b) ; Copp iai nt . azz eraPr imo(b ); Coppia lnt . scambi aEl ementi (b); stampaCopp ia( b) ; otate che, come ne ll a oluzione dell' esercizio 3.86, i devono scam biare gli elementi di b due volte. Se in fatti b contiene la coppia [ 1 : 7] e i chiede al programmatore di azzerare la econda compo nente, ci i a petta che all a fi ne la coppia b ia [ 1 : 0] ; e cri viamo Coppia ln t .azzera Primo (b); Coppia ln t . scambiaEl eme nt i( b) ; è vero che abbiamo ottenuto una coppi a con la seconda componente uguale a zero, ma non quell a che ci si asp ttava. Notate anche che i metodi scamb i aE l ement i e a zz eraPr i mo devono e ere invocati premettendo il nome de ll a eia se Copp i aint perché ono dichiarati . latic i

8.3 I tipi di da to astraiti

199

in quella eia e e e li si vuole u are i deve "dire a Java dove trovarli " ( edremo pre to che que to modo di program mare cambi a con la vi ion a oggetti ). Il metodo s tampaCopp i a invece può e ere chiamato senza premetterg li il nome della ei a e perché è dichi arato e usato nell a te a eia e UsoCopp i ain t e quindi "Java a dove trovarlo" . Se azzeraPrimo fo e tato critto in er ione fun zionaJe, avremmo potuto crivere anche in que to modo:

Copp ia in t . scambiaEle ment i( b); Copp ia i nt.scamb iaEl emen ti( Coppiaint.azzeraPrimo(b) );

stampaCopp ia (b ) ;

E e anche scambiaElementi fo e tato critto in modo fun zionale cri vere st ampaCoppia( Coppi aint .scambiaEleme nti( Copp ia int. azz er aPr i mo( Coppi aint .scambia Eleme nti( b))));

poteva



Esercizio 3.91 Il metodo ha bi ogno di tre param tri : la coppia e i due componenti nuov i. Se lo cri viamo in modo proceduraJ e otteniamo: public static voi d set (Coppia in t c, int pr i mo, int sec ondo ) { c.x pr imo; c .y sec ondo; }

Se lo criviamo in modo fun zionaJe otteniamo invece:

publ ic s t atic Coppiaint set( Coppia int c , i nt pr i mo , i nt sec ondo) { c.x = primo ; c .y = secondo; return e; }

(come aJ oljto so no ev idenziate le unjche di ffe renze).



Esercizio 3.92 In que to ca o abbi am o a che fare con un metodo che deve re tituire un valore. A di ffere nza dei ca i precedenti quindi non dovre mo cegliere e criverl o in modo fun zionaJe o procedurale: un metodo che restitui ce un vaJore deve per forza e ere una funzione. Il codjce è: publi c st atic i nt getSomma(Coppiaint c ) { return c.x+c.y; }



Esercizio 3.93 Se scegliamo di cri vere i metodi in ver ione proceduraJe otterremo:

200

Soluzioni del capitolo 3

public static vo i d invertiPrimo(Coppiaint c) { c.x = -c.x; public static void in vert i Secondo(Coppia int e) { c.y = -c.y;

Se invece cegliamo di scrivere i metodi in ver ione fun zionale avremo: publ ic static Copp ia in t i nvertiPr i mo (Coppia int c) { c.x = -c.x; return c; publ ic static Coppiaint inve rt i Secondo (Copp ia int c) { c.y = -c.y; return c;



Esercizio 3.94 La ottrazione del primo meno il econdo componente di e i può ottenere con getSomma dopo aver invertito il egno del econdo componente con invertiSecondo . Se abbiamo critto invertiSecondo in ver ione proceduraJe allora dobbiamo aggiungere aJla fine del main di UsoCoppiaint le ri ghe: Copp ia int .invertiSecondo(c); System.ou t .println( ' Il r is ultato del pr imo meno il secondo ' + "componente di ce ' • + Copp i aint . getSomma(c)); Coppiaint . invertiSecondo(c);

Notate che i deve invertire due volte, prima e dopo getSomma, in modo da ri portare la econda componente di e aJlo tato originario. Se abbiamo definito invertiSecondo in modo fun zionale pos iamo scrivere anche: System.out . pr i ntln( ' Il risultato del pr imo meno il secondo "+ ' componente di c e ' ' + Coppiai nt.g etSomma(C oppiaint.i nvertiSec ondo (c))); c = Coppia int.invert i Secondo(c );

8.3.3



I costruttori

Esercizio 3.95 In un TDA pos ono e ere presenti più co truttori purché abbiano numero o tipo dei parametri diver o. In questo ca o dobbiamo aggiungere un co truttore con un olo parametro. Il codice arà una leggera modifica di quello già pre ente nel TDA: public Copp ia lnt(int unico) { x = unico; y = unico ; }

.3 I tipi di da to astraiti

201

(invece di a egnare a x il primo parametro e a y il econdo, a egnam o a entrambi l' unico parametro) .



Esercizio 3.96 Anche in que to ca o, come ne ll 'e erc izio 3.95 , po iamo aggiungere il co truttore perché ha un parametro di tipo di ver o dal precedente. Il codi ce public Coppia lnt(Copp i al nt c ) {

x

c.x;

Y = c. y; otate che in questo ca o non erve u are i metodi ge t Pr i mo e getSecondo (anche ·e usarli non arebbe un errore) perché iamo all ' interno de ll a eia e Copp i alnt e quindi abbiamo acce o ai campi pri vati .



Esercizio 3.97 È uffic iente aggiungere all a fi ne di UsoCopp i aint le eguenti righe di codice: a = new Coppi ain t(323 ) ; // pun t o st am paCopp i alnt (a) ; b = new Coppia ln t(a ); // punto 2 Copp ia lnt.set Sec ondo(b , Legg i. unln t ( )); stampaCoppia in t( b) ;



Esercizio 3.98 Un co truttore che crea una coppi a con i numeri letti da ta tiera non ha bi ogno di ne un parametro: public Copp ia lnt ( ) { x = Legg i .u nlnt( ); y = Leggi.u nlnt( ); e volete potete far vi ualizzare un me aggio in que to modo: public Copp ialnt () { Syst em . out . pri nt ( • In s er isci il pr imo componente: • ); x = Legg i.u nlnt() ; Sys t em.out. pri nt ( "In se r isci i l seco nd o compo ne nte: ' ) ; y = Legg i. unint( ) ; }

8.3.4

.

Definire nuovi TDA

Esercizio 3.101 Vi ono molti modi di ver i per impl ementare il TDA Freccia. Un' implementazione è mi gliore di un ' altra e rende la vita del programmatore più emplice: è più effi ciente, più fac ile da u are, da manutenere, da estendere, da verificare ... Per operare una buona ce lta dobbiamo vedere qual i operazioni devono es ere con entite dal TDA . In ba e a que te po iamo dec idere come implementarlo al meglio.

202

Soluzioni del capitolo 3

Un primo modo, emplice, di implementare il TDA con iste nell ' usar variabili private, una per la lunghezza e una per il ver o:

due

class Freccia { private i nt lunghezza; pr i vate char verso; public Freccia(int lun, char v) { lunghezza = lun; verso = v;

}

Ad una prima occhiata il co truttore potrebbe sembrare corretto, ma co a uccederebbe e in un programma che u a il TDA il programmatore crives e Freccia f = new Freccia( - 4, ' s ' ); ? Cosa vuol dire creare una freccia di lunghezza -4? Il costruttore che abbiamo critto non farebbe una pi ega e que to non va bene. Se vog li amo defi ni_re un TDA che rappre enta una freccia, allora dobbiamo fare in modo che il costruttore non accetti lunghezze negati ve. [noltre dobbi amo defi nire una convenzione u come rappresentare il ver o: non tutti i caratteri andranno bene come econdo parametro del costruttore e ne pos iamo (dobbi amo) scegli ere due p r fare in modo che la variabile pri vata verso abbia empre come vaJore uno ed uno olo dei due caratteri scelti. Un co truttore corretto che controlla gli argomenti e scrive anch messaggi di errore (il Java in rea ltà mette a di sposizione un meccani mo più elegante per ge tire que ti ca i "eccezionali", I eccezioni , si veda il paragrafo 5. 1.1 ) public Freccia(i nt l un, char v) { lunghezza = (lun < 0) 7 0: lun; if (lun < 0) System. out . pr i ntln ( ' Errore: non e ' permessa un a "+ ' freccia di lunghezza negativa. La freccia viene ' + ' creata con l unghe zza par i a zero" ); verso = (v == ' d ' : : lunghezza == 0) 7 ' d ' : ' s ' ; i f (v I= ' s ' && V I= ' d ' ) Syst em.out . pr intl n( "Errore: il ver so di una freccia "+ ' puo ' essere solo 's ' per sinistra o ' d ' per '+ ' de st ra. La freccia viene creata con verso ' s '' ); otate che, per convenzione, e la lunghezza interna della freccia lunghezza è uguale a zero allora il ver o è ' d ' . Que ta convenzione è puramente arbitraria ed il programmatore potrebbe fare quaJ ia i aJtra scelta, purché sensata e coerente. Il metodo allunga ha un parametro di tipo Freccia e uno di tipo int (che dobbi amo controllare es ere magg iore di zero): publ ic static void allunga(Freccia f, int allungamento) {

.3 I tipi di dato astrai/i

203

if (allungamento < 0) System.out.println( ' Errore: non si puo ' allungare ' + "una freccia di una quantita ' negativa. ' ); else f.lunghezza += allungamento; [I metodo per accorciare una freccia è un po' più compie o perché se i accorcia una freccia oltre la ua lunghezza i ottiene una freccia con ver o contrario. La er ione procedurale :

public static void accorcia(Freccia f, int accorciamento) { if (accorciamento < 0) System.out.println( "Errore: non si puo ' accorciare '+ ' una freccia di una quantita ' negativa. ' ); else if (accorciamento == f.lunghezza) { f.lunghezza = 0; f.verso = ' d ' ; } else if (accorciamento> f.lunghezza) { f.lunghezza = - (f.lunghezza-accorciamento); f. verso = (f. verso == ' s ' ) 7 ' d ' : ' s ' ; } else f.lunghezza -= accorciamento; }

Que to metodo per prima co a controlla e il econdo parametro è sensato ( e non è co ì, non fa nulla) . Se i vuole accorciare la freccia di una quantità pari alla ua lunghezza allora la lunghezza la lunghezza viene po ta a zero e il ver o, per convenzione, a ' d' (destra). Altrimenti e i accorcia la freccia di una quantità uperiore aJla ua lunghezza occorre cambiarne ia il egno ( - (f. lunghezza - accorciamento)), perché diverrebbe negativo, ia il ver o. L'ultimo ca o i ha quando i accorcia di una quantità minore della lunghezza. Que to è il ca o più emplice in cui ba ta togliere accorciamento . Per apere e una freccia va verso de tra o ver o sinistra po iamo scrivere due metodi :

public static boolean vaVersoDestra(Freccia f) { return f.verso == ' d ' ; }

public static boolean vaVersoSinistra(Freccia f) { return f.verso == ' s ' ; (in rea.ltà, dato che una freccia va o ver o de tra o ver o m1 tra, e non ono po sibili altri ca i, ba terebbe definire anche uno olo dei due metodi precedenti). li metodo per apere la lunghezza è semplicemente:

public static int lunghezza(Freccia f) {

Soluzioni del capitolo 3

204

return f.l unghe zza; Una freccia somma di altre due si otti ene così: se hanno lo stes o ver o si ommano le loro lunghezze; aJtrimenti la freccia ri ultato avrà il ver o de lla più lunga e la lunghezza data dalla differenza de lle due lunghezze. Il metodo è:

public static Freccia somma(Freccia f1, Freccia f2) { if (f1.verso == f 2.verso) return new Freccia(f1.lunghezza+f2.lunghezza, f 1. verso); else { Freccia f = new Frecc ia (f1.lunghezza, f 1. verso) ; accorcia(f,f2.lunghezza); return f; }

Se le frecce hanno lo te o ver o ba ta creare con il costruttore una nuova freccia e pa are come primo parametro la omma delle lunghezze e come econdo uno dei due ver i (e endo uguaJi uno vaJe l'aJtro). Se invece i ver i ono oppo ti i può creare una nuova freccia con lo te o ver o e lunghezza de ll a prima e poi accorciarl a di tanto quanto è lunga la econda . Se questa è più lunga della prima ci pen erà il metodo accorcia ad aggiustare il ver o. otate quante linee di codice ono tate pe e per mantenere la struttura dati coerente (tutti i controlli fatti con if e operatori condi zionaJi ). L' incap ularnento (cioè l'aver dichiarato le variabili private) permette aJ programmatore del TDA di a icurare e mantenere la coerenza: non c i sarà mai una freccia di lunghezza zero con ver o a ini tra. Se le variabili non fos ero private questa coerenza non potrebbe e ere garantita, in quanto arebbe pos ibile modificare a piacimento ver o e lunghezza di una frecc ia. n tipo Freccia pu e ere implementato anche in un aJtro modo, memorizzando solo la lunghezza: se negati va o zero si considera la freccia orientata ver o de tra, e po itiva verso sini tra. Que ta codifica (negativa significa de tra e positiva significa ini tra) deve rimanere na costa all'interno del TDA . Il costruttore e i metodi devono mantenere le stes e intestazioni e soprattutto lo ste so uso; e non i deve obbligare l' utilizzato re del TDA a cono cerne la codifica interna: questi dovrà continuare ad usarlo come se fo e una cosa che non può avere lunghezza negativa e che ha un verso, anche se po i, internam ente, l' informaz ione viene memori zzata in una forma diversa. Il codice potrebbe es ere:

public class Freccia { /* Rappresento una freccia internamente solo con la lunghezza. Se e ' pos i tiva rappresenta una freccia verso sinistra, se e ' negativa o ze ro va verso destra. */ private int lunghezza;

8.3 I tipi di dato astrai/i

public Freccia(int lun, char v) { lunghezza = (lun > 0) ? l un : 0; if (lun < 0) System.out.pri ntln( ' Errore: non e ' permessa •+ ' una freccia di lunghezza negat iva. La freccia "+ ' viene creata con lunghezza pari a zero ' ); lunghezza = ( v == ' s ' ) ? lunghezza : -lunghezza; if (v I= ' s ' && V I= ' d ' ) System.out . println( ' Errore : il verso di una •+ ' frecc i a puo ' essere solo ' s' per sinistra o ' d ' • + ' per destra. La freccia viene creata con verso ' s '' ); public static void accorcia(Freccia f, int accorciamento) { if (accorciamento < 0) System.out.pri ntln( ' Errore: non si puo ' •+ ' accorciare una freccia di una quantita ' negativa. ' ); else f . lunghezza -= vaVersoDestra(f) ? -accorciamento accorciamento; }

public static void allunga(Freccia f, int allungamento) { if (allungamento < 0) System. out . pr i ntln ( •Errore: non si puo ' "+ "allungare una freccia di una quant ita' negativa. " ); else f .lunghezza += vaVersoDestra(f) ? -allungamento allungamento; }

public static boolean vaVersoSinistra(Freccia f) { return f .lu nghezza > 0; }

public static boolean vaVersoDestra(Freccia f) { return f.lunghezza = 24 vi ene cons i derato h=23 se h < 0 viene considerato h=0 analogamente per minuti e secondi, il valore e ' sempre compreso tra 0 e 59.

*/

publ i c Ora(byte ore, byte minuti, byte secondi) { h ore >23 ? 23 : (ore 59? 59: (minuti 59? 59: (secondi 0) { aggiung i Mi nu ti( ora ,(byte) ( (ora.s+second i ) / 60)) ; ora.s = (byte)((ora.s +second i )\ 60); } }

,.... .,

* Agg i unge mi nut i so l o se sono i n numero po sit i vo

public static vo i d agg i ungiMinu ti (O ra ora , byte min ut i ) { i f (mi nut i> 0) { agg i ung i Ore(ora , (byte) ( (or a. m+mi nut i) / 60)) ; ora.m = (byte ) ((ora. m+mi nu ti )\ 60); }

,.... .,

* Agg i ung e ore sol o se sono i n nume ro po sitivo

publi c static voi d agg i ung i Or e (Or a ora, byte or e) { or a.h = (byte)(( (ore>0?ore:0 )+ora . h) %24) ; }

Con que ta soluzione abbiamo celto di non visual izzare mes aggi di errore se il costruttore viene invocato passandogli parametri che non corri pondono direttamente a un orario del giorno. I parametri vengono automaticamente "aggiu lati". otale però che que ta scelta, che è del tutto arbitraria, viene egnaJata agli eventuali utili zzatori del TDA tramite un commento j avadoc. Analogamente i metodi aggiungiSecondi, aggiung i Mi nu ti e agg i ung i Ore hanno commenti javadoc che piegano le scelte implementati ve. Notale infine che nei metodi agg i ung i Secondi e agg i ung i Minut i , il ca o in cui i tenti di aggiungere un numero di ·econdi (o minuti ) che fa aumentare la cifra dei minuti (o delle ore) viene ge tilo u ando una chi amata aJ metodo relativo. Ad e empio, e i invoca aggiungiSecondi pa ando come parametri l'ora 3: 08: 46 e i econdi 327, prima verranno aggiunti 6 minuti con il metodo aggiungiMinuti e poi 13 econdi con I' as egnamento or a . s =



Esercizio 3.104 publi c cl ass UsoTDAOr a { publi c stat i c void mai n(Str i ng[J args ) { Ora a = new Ora(Legg i .u nByte() , Leggi.unByte ( ), Legg i .unByte()) ; System.out.pri ntln(pr i ntOra(a)); Ora.aggiungi0re(a , (byte)3 );

8.3 I tipi di dato astratti

209

System.out.println(printOra(a)); Ora.aggiungiMinuti(a,(byte)32); System.out.println(printOra(a)); Ora.aggiungiSecondi(a,(byte)12); System.out.println(printOra(a)); Ora.aggiungiOre(a,(byte) -32); System.out.println(printOra(a)); }

private static String printOra(Ora a) { return (Ora.get0re(a) somma) { System.out.pri ntln( ' Non ci sono abbastanza soldi ' ); somma = 0; } else somma -- euro;

Come abbiamo fatto per aggiungilire pos iamo implementare toglilire u ando togliEuro : public void toglilire{int lire) { togliEuro (lire/ CAMBIO_LIRA_EURO);

Grazie alla celta di mantenere la somma contenuta nel portafogli memori zzata nell a variabile somma, il metodo quantiSoldi diventa molto emplice: publi c float quant i Sold i () { return somma; }

Anche il metodo alVerde è semplice: e i oldi ono zero ritorna true , altrimenti false . Sappiamo che ogni volta che trov iamo lo chema se condizione allora ritorna true altrimenti ritorna false po iamo sempre ostituirlo con l'istruzione che re titui sce la condizione del e (return "i oldi sono zero" in que to caso):

1Sarebbe

più corretto u are il meccani mo delle eccezioni . che incontreremo più avanli .

216

Soluzioni del capitolo 4

pub lic boo lean alVerde() { return (somma == 0);

• Esercizio 4.9 Per creare un oggetto x di tipo Portafog li dobbiamo usare il co truttore:

public class UsoPortafogli { public static void main(String[J args) { Portafogli x = new Portafogli(); } }

Per far in erire 4 vo lte un numero di euro da tasti era ed aggiungerli al portafogli x, criveremo un cic lo:

for (int i = 1; i< = 4 ; i++) { Sy stem . out.print( "Quanti euro vuoi agg iungere? "); x. aggiungiE uro(Leggi .unFloat( )); otate che per far leggere il numero da ta tiera u iamo il metodo unFloat della e ia e Leggi e che il ri ultato re titui to dall a chiamata di que to metodo non viene messo in una vari abile, ma direttamente pa alo come parametro attuale al metodo aggiungiE uro . otate anche che di ver ament dal ca o TD , il metodo non vien chiamato u ando il nome d Ila eia e, ma la variab ile. el ca o TDA avremmo critto Port afogli . aggiungiEuro ( x, Leggi. unFloat ()) invece di x.aggiungiEuro(Leggi.unFloat()) . Pro guendo con l'e erc izio, far aggiungere un numero di lire lette da tastiera e poi , per 4 vo lte far tog li ere lire e in fine eur letti da ta tiera an alogo a prima. Bi ogna o lo cambi are unFloat in unint quando si tratta di lire invece di euro e chi amare i metodi giusti :

System.out.print (' Ou ante lire vuoi aggiun ge re? ' ); x. aggiungiLire(Leggi.unint()); for (int i = 1; i java U10Portafogli Quanti euro vuoi aggiungere? 2 Quanti euro vuoi aggiungere? 3 Quanti euro vuoi aggiungere? 4 Quanti euro vuoi aggiungere? 1 Quante lire vuoi aggiungere? 12eN Quante lire vuoi togliere? 25" Quante lire vuoi togliere? 4Ht Quante lire vuoi togliere? 3H Quante lire vuoi togliere? 215e Quanti euro vuoi togliere? 2.28 ••no • alel Sono ri• a1ti 9.29 euro

• Esercizio 4.10 Per aggiungere un array di n portafogli dobbiamo leggere da ta tiera il valore e i tanziare il nuovo array: System.out . printl n(" Ouan ti portafogli? ' ); i nt n = Leggi.unlnt(); Portafogli[ ] p = new Portafogli[n];

Nota Per ora p non contiene n portafogli , ma è olo un array lungo n con "lo pazio" per n portafogli . Per creare gli n portafogli occorrerà invocare n volte il co truttore della eia e Portafogli .

Soluzioni del capitolo 4

218

Per ogni portafogli dobbiamo chiedere 7 volte che operazione si vuole fare e di quale entità. Per ottenere questo ri sultato criveremo un ciclo, lungo quanto l' array di portafogli, che contiene un altro ciclo, quello delle 7 richieste. Notate che la prima istruzione del ciclo esterno sarà la creazione del portafogli i-esimo. Il codice avrà questa struttura: for ( int i ... ) { // per tutti gli elementi dell ' array p . . . new Portafogli(); // creo il portafogli i -esimo for (int j .. . ) { / / per 7 volte // codice per leggere da tastiera // quale operazione eseguire // codice per eseguire l ' operazione }

Scrivendo il codice al posto dei puntini otteniamo: for (int i = 0; i< p.length; i++ ) { // per tutti gli elementi dell 'a rray p p(il = new Portafogli(); //creo il portafogli i -esimo System.out.println( ' Portafogli ' +(i+1)); for (int j = 1; j DIMENSIONE_MASSIMA? DIMENSIONE_MASSIMA: dimensione; this.dati = new boolean[dimensione][dimensione1; }

La riga pas ata come parametro rappre enta la riga della cacchiera che· i vuole elezionare. Salveremo que to valore nella variabile riga facendo però attenzione che la riga l della cacchiera corri ponde alla riga O della matrice dati. Aggiungeremo quindi this.riga = riga -1;

otate che nell'i truzione precedente this. riga i riferi ce alla variabile privata riga dell ' i tanza di ScacchieraScomoda, mentre riga - 1 i riferi ce al vaJore del parametro riga del co truttore. Se ave simo scritto riga = riga -1;

222

Soluzioni del capitolo 4

avremmo emplicemente modificato il valore del parametro e non il valore dell a variabile privata. Per la colonn a il procedimento è analogo a prima: variabile e parametro hanno lo ste o identificatore e dunque, come prima, per riferirci all a variabile u eremo this. colonna e per riferirci al parametro olo colonna. C' è per una complicazione: il parametro è di tipo char e la co lonna ' a ' corri ponde alla co lonna Od Il a matrice dati . Tenendo presente quanto detto, il codi ce del co truttore di venta: public ScacchieraScomoda ( i nt dimensione, i nt riga , char colonna ) { dime ns i one = dimensione >DIMENSIONE_MASSIMA? DIMENSIONE_MASSIMA: dimension e; this.dati = new boolean[d imension e][ dimensio ne ] ; this.riga = riga -1; this. colonna = colonna . ' a ' ; }

Manca ancora un dettaglio, il controll o dell 'i nput: ri ga e colonna devono e ere compre i fra . . .

Nota



Esercizio 4.18 li co truttore enza parametri dovrà emplicemente chi amare qu Ilo che abbiamo definito nell a soluzione dell ' e ercizio precedente pa andogli i parametri giu ti : publ ic Scacc hi eraS comod a() { th i s(B,1, ' a ' ) ; }

otate che l' altro co truttore viene chiamato u ando il this e non con l'i truzione ScacchieraScomoda ( 8, 1, ' a ' ) . Se face imo in que to econdo modo, il compilatore darebbe un me aggio di errore di questo tipo: > javac Scecchieralco• oda Scacchieralcoaoda.java:15: cannot re•olve 8y• bol 8y• bol : • ethod Scacchieralco• oda (int,int,char) location: cl••• lcacchieralco• oda Scacchieralco• oda(l,1,'a');

1 error

..



Esercizio 4.19 Per creare un nuovo oggetto di tipo Scacch i eraScomoda ba ta di chi ararlo e chiamare il co truttore:

9.1 Dai tipi di dato a traui agli oggeui

223

class UsoScacchie raScomoda { publ ic static void main(String[) args) { ScacchieraScomoda s = new Scacc hieraScomoda ( ) ;

metti è un metodo di eia e e non di i tanza, quindi per invocarlo criveremo

s .metti( ); lnfin , per Lampare la cacchi ra, vi lo che ScacchieraScomoda ha il metodo toString, l'unica i truzion da aggiungere è

System.out.println(s); Il codice finale di UsoScacchieraScomoda è:

class UsoScacchi eraScomoda { public static void main(String[) args) { ScacchieraScomoda s = new Scacchi eraScomoda(); s.metti(); System . out .p rintln(s); } }



Esercizio 4.20 li metodo è d' i tanza e quindi non deve e ere static . Per elezionare la ri ga e la colonna pas ate come parametri dobbiamo eguire lo te o ragionamento che abbiamo fatto per il co truttore. li codice del metodo, da aggiungere alla eia e ScacchieraScomoda, è: publ ic voi d selezion aCella(i nt riga, char colonna) { this.riga = r i ga -1; this . colonna = colonna - ' a ' ; Per cr are una nuova cacchiera s2 po iamo u are il co trultore con tre param etri e elezionare per prima co a la cella 1 , a :

Scacch ieraScomoda s2

=

new Scacc hieraScomoda(2,1, ' a ' );

Per occupare la cella selezionata dobbiamo chiamare il metodo metti :

s2 .metti(); Fatto que to dobbiamo elezionare la cella 2, b e occuparla:

s2.selezionaCella(2 , ' b ' ); s2 .metti(); Infine dobbiamo lampare la cacchiera:

System .ou t.println(s2); Il codice finale di UsoScacchieraScomoda arà:

224

Solu zioni del capitolo 4

class UsoScacch ieraScomoda { publ ic static void main(String[J args) { ScacchieraScomoda s = new ScacchieraScomoda(); s . metti(); System.out.println(s); ScacchieraScomoda s2 = new Scacch ieraScomoda(2,1, ' a ' ); s2. metti ( ) ; s2.selezionaCella(2, ' b ' ); s2. metti(); System.out.println(s2); } }

Ovviamente, anche scambiando i parametri del co truttore e di selezionaCella si ottiene lo tes o ri sultato: Scacch ieraScomoda s2 = new ScacchieraScomoda(2,2, 'b'); s2. metti() ; s2. selezionaCella ( 1, 'a') ; s2.metti();



Esercizio 4.21 Osserviamo che i ' + ' compaiono nelle colonne di indice pari (0,2,4, ... ). li codice, con le modifiche evidenziate, è il eguente: public String toString() { int dimensione = dati.length; String temp = • "; for (int i = 0 ; i */ import java.awt .* ; import java.awt.event.*; import java.applet .* ; public class App2 extends Applet { public void init() { Button bRosso = new Button( "rosso "); Button bVerde = new Button( "verde "); bRosso.addActionListener(new Colora(Color.red,this)); bVerde.addActionListener(new Colora(Color.green,this)); add(bRosso); add(bVerde); class Colora implements ActionL i stener { private Color e; private Component co; public Colora(Color e, Component co) { this.c = e; this.co = co; }

public void actionPerformed(ActionEvent e) { co.setBackground(c); co . repaint(1); }

} }



Esercizio 5.44 Per di egnare u un componente si deve ovrascrivere il uo metodo paint aggiungendo il codice nece ario a di egnare quello che vogliamo. I primi puntini vanno o tituiti con:

264

Soluzioni del capitolo 5

f.add(new Disegnaauadrato(12));

Il codice del metodo paint è: Dimension d = getSize(); g.drawRect((d.width -lato)/2,(d.height -lato)/2,lato,lato);



Esercizio 5.46 Si deve modificare DisegnaQuadrato nel modo seguente: class Disegnaauadrato extends Canvas { private int lato; private int x; private int y; public Disegnaauadrato(int lato) { this.lato = lato; this . x = lato; this.y = lato; this.addMouselistener(new Spostaauadrato()); }

public void paint(Graphics g) { g . drawRect(x -lato/2,y -lato/2,lato,lato); }

class Spostaauadrato extends MouseAdapter { public void mouseClicked(MouseEvent e) { x = e.getX(); y = e.getY(); repaint(1); }

• Esercizio 5.47 Una prima soluzione consiste nel modificare il metodo add in questo modo: void add(int x, int y) { this.x[n) = x; this.y[n] = y; this.n = (this.n+1)%MAX_ELEM; }

Facendo cosl però all'undicesimo click non verranno visualizzati i cerchi perché n varrà zero e l'istruzione nel for del paint non verrà eseguita neanche una volta. Per la soluzione completa, che all'undicesimo click fa sparire solo il primo cerchio e disegna l'undicesimo, dobbiamo aggiungere una variabile piuDiNClick alla classe DisegnoApplet: boolean piuDiNClick

=

false;

10.2 Le interfacce grafiche

265

Questa variabile serve a sapere se sono stati fatti più di n click. Quindi possiamo modificare i metodi paint e add nel seguente modo: public void paint(Graphics abc) { for (int i = 0; i< (piuDiNClick?MAX_ELEM:n); i++) abc.drawOval(x[i)-this.R,y[i) -this.R,this.R*2,this.R*2); }

void add(int x, int y) { this.x[n] = x; this.y[n) = y; this.n = (this.n+1)%MAX_ELEM; piuDiNClick = piuDiNClick : : this.n }

0;



Una conclusione? [... ] un ri camo fatto ul nulla che a omigli a a que to filo d' inchio tro, come l' ho la ciato correre per pagine e pagine, zeppo di cancell ature, di rimandi , di gorbi nervosi, di macchie, di lacune, che a momenti i grana in grossi acini chiari , a momenti si infitti ce in egni minu coli come emi puntiformi, ora i ritorce su e te o, ora i bi fo rca, ora collega grumi di fra i con contorni di foglie o di nuvole, e poi ' intoppa, e poi ripigli a a attorcigliar i, e corre e corre e i dipana e avvolge un ultimo grappolo insen ato di parole idee ogni ed è finito. Italo Calvino Coi nostri " fili d' inchio tro" , con gli e ercizi e le soluzioni proposte in que to testo, abbiamo cercato di convincervi che l'aver tudiato u un qualsia i buon libro di programmazione in lava non aveva fa tto di voi dei "veri " programmatori . Ora, tenetev i forte, vorremmo convincervi che neanche l' averci eguito fin qui , "facendo" a più non po o, è abbastanza. Prima che vi demorali zziate, preci iamo che chi ben cominc ia è a metà dell ' opera e e iete arrivati fin qui ignifica che avete be n cominciato. Da un punto di vi ta " tecnico" avete cono ciuto, u ato e sperimentato gli ingredienti di ba e di un programma lava : i tipi predefiniti , le e pres ioni , la programmazione trutturata, la ge tione deg li array, la potenza della ricor ione, lo viluppo incrementale dei programmi , il cicl o editing-compilazione-e ecuzione, la crittura e l' uso dei metodi , l' importanza dell ' occultamento delle informazioni , le tecniche di implementazione dei tipi di dato astratti , i concetti di cambio me aggi, ereditarietà e polimorfi smo, che ono i principi di ba e della programmazione ori entata agli oggetti , e i rudimenti dell ' uso delle API Java. Abbiamo anche in i tito u a petti più pecifici, ma che pesso ri ultano di più difficile compren ione, quaJi l' operatore di modulo, il tipo boo leano, i cic li annidati , il pa aggio parametri . Da un altro punto di vista, che potremmo definire "caratteri ale" e che, per certi versi, è fo rse il più importante, speriamo di avervi tra me so il gu to per due ingredienti fo ndam entali dello spirito di un buon programmatore: l' attenzione ai dettagli e la continua ricerca di oluzioni mi gli ori . L' imprec isione, l' approssimazione e la fretta ono i peggiori nemici del software di qualità. Speriamo inceramente che ne lla vostra carriera di programmatori , breve o lunga, non abbracciate mai la fil o ofi a del

268

Una conclusione?

"basi' chefunz "'. Un terzo ingrecliente, empre cli tipo caratteriale, è l'inclinazione allo tuclio continuo. Su di es o abbiamo in i tito poco, ma va da é che senza una continua attività di aggiornamento non è pos ibile e ere dei buoni programmatori. Quincli non c' è dubbio che di trada in ieme ne abbiamo fatta , e parecchia. Ma molto re ta ancora da fare . Come abbiamo già accennato, abbiamo olo fiorato alcuni aspetti della programmazione in Java (ad esempio la ge tione delle eccezioni o il paradigma object oriented). Altri a petti non sono tati neppure accennati (ad e empio, le as erzioni, i tipi parametrici, o il multithreading). Lo terminato mondo delle API, cli cui abbiamo visto solo la superficie della punta dell'iceberg, è lì ad attendervi. Abbiamo parlato olo di Java Standard Edition, che va bene per cominciare ma non basta e volete viluppare applicazioni Web (in tal caso dovete familiarizzare con J2EE, Java 2 Enterpri e Edition, e con le ue API) o applicazioni per di positivi mobili (e in tal caso dovete familiarizzare con J2ME, Java 2 Micro Edition). E e tutto questo non vi basta, potete empre avventurarvi nel mondo delle tecniche di buona progettazione e analisi orientate agli oggetti: i pattern di progetto, il progetto per contratti, o formali mi piutto to comples i come lo Unified Modelling Language (UML).

Ma questa è un ' altra toria . ..

Informazioni sugli Autori public class InfoAutori { public static void main(String[] args) { stampainfoCoppola(); stampainfoMizzaro(); static void stampainfoCoppola() { System.out.println( ' Paolo Coppola • +' e ' ricercatore presso l ' Un i versita ' di Udine, • +' Dipartimento di Matematica e Informatica. Si • +'interessa di implementazione ottimale di linguaggi • +' di programmazione funzionale, di sviluppo di • +' applicazioni per dispositivi mobili, di reti ' +' neurali e di informatica per gli archivi e per le • +' biblioteche . Ha esperienza pluriennale di ' +' programmazione e insegnamento del linguaggio Java • +' sia in ambito accademico, sia presso le aziende ." ); }

static void stampainfoMizzaro() { System.out.println( ' Stefano Mizzaro • +' e ' ricercatore presso l ' Universita di Udine, • +' Facolta ' di Scienze Matematiche Fisiche e • +' Naturali, Dipartimento di Matematica e • +' Informatica . I suoi interessi di ricerca sono • +' l ' information retrieval, le biblioteche digitali • +" e la diffusione della cultura scientifica, lo • +"sviluppo di software orientato agli oggetti e le • +' applicazioni per dispositivi mobili: in questi ' +' settori ha pubblicato quasi 50 lavori, comprendenti • +' articoli su riviste, atti di convegni e libri. • +' E' autore del libro Introduzione alla • +' programmazione con il linguaggio Java, • +' Franco Angeli, 2002 (3a ed .). Ha esperienza • +' pluriennale di insegnamento in ambito universitario • +' e di consulenza presso aziende. ' ); }