18
Programmazione Corso di Informatica per la 3° Liceo Scientifico opzione Scienze Applicate Alessandro De Nardi

Dispensa di Programmazione173.236.60.18/~ricecode/SCUOLA/3C/DispensadiProgrammazione.pdfPrefazione Questo testo è in continua evoluzione. Per ora è una raccolta di riassunti delle

  • Upload
    buidung

  • View
    217

  • Download
    0

Embed Size (px)

Citation preview

Programmazione

Corso di Informatica per la 3° Liceo Scientifico opzione Scienze Applicate

Alessandro De Nardi

PrefazioneQuesto testo è in continua evoluzione. Per ora è una raccolta di riassunti delle lezioni più importanti del corso di Informatica in 3°C Liceo Scientifico opzione Scienze Applicate M. Flaminio di Vittorio Veneto. In particolare, è trattata la teoria di base della programmazione procedurale e della programmazione orientata agli oggetti.Quest’opera è rilasciata con licenza CC_BY-NC-SA_3.0. Per informazioni contattare informaticaflaminio <chiocciola> gmail <punto> com.

Indice1. I programmi

Accenni storiciCompilazione e interpretazioneCiclo di vita

2. Concetti di base di un linguaggio di programmazioneGrammaticaDati

VariabileTipo

Comandi che agiscono sui datiDichiarazioneAssegnamentoAltri operatoriProcedureFunzioni

Comandi che agiscono sul flusso di esecuzioneIstruzione condizionale: ifIstruzione iterativa con guardia: whileIstruzione iterativa con contatore: for

3. La programmazione orientata agli oggettiClassi ed oggetti

Definizione di una classeDefinizione degli attributiDefinizione dei metodiCreazione degli oggettiManipolazione degli oggetti

1. I programmi

DefinizioniAlgoritmo: procedimento descrivibile in forma di sequenza finita di istruzioni che risolve un determinato problema.Linguaggio di programmazione: linguaggio artificiale usato per descrivere formalmente algoritmi in modo che questi possano essere eseguiti da un computer.Programma: algoritmo realizzato con un linguaggio di programmazione.

Accenni storiciNel 1833 Charles Babbage progettò la Macchina Analitica, il primo vero calcolatore programmabile, in senso moderno, della storia. Venne realizzato solo il mulino (vedi figura a sinistra), cioè la CPU, ma non ne fu mai realizzato un prototipo completo. Era il primo esempio di macchina con un'unità di memoria ed un'unità di calcolo.Nel 1842 la contessa di Lovelace, Ada Byron, figlia

del poeta Lord Byron, scrisse i primi programmi della storia, pensati per essere eseguiti sulla macchina analitica. Sebbene la macchina di Babbage non venne mai costruita, gli studi della Lovelace sono importanti per la storia del computer. Ada Lovelace aveva previsto anche la capacità dei computer di andare al di là del mero calcolo numerico, mentre altri, incluso lo stesso Babbage, si focalizzarono soltanto su queste capacità.Dagli anni venti agli anni cinquanta, i programmi si scrivevano in schede perforate (vedi figura a sinistra),

utilizzate fino a poco prima per regolare i motivi ornamentali da riprodurre sulla stoffa con i telai. Più tardi le schede perforate furono soppiantate dai più moderni supporti di memorizzazione di dati come nastri, floppy disk, CD-ROM e DVD.

Compilazione e interpretazioneIl codice sorgente di un programma è la rappresentazione di un algoritmo in un linguaggio di programmazione, solitamente in formato testuale. I primi codici scritti erano composti da sequenze di istruzioni eseguibili direttamente dal processore. Dal momento che la CPU è in grado di svolgere solo semplici operazioni, i programmi dovevano combinare molte istruzioni per implementare1 un algoritmo non banale e per di più con una sintassi assai ostica (fatta di numeri binari). In queste condizioni era difficile evitare di commettere errori nella stesura di un programma.I moderni linguaggi di programmazione sono detti ad alto livello in quanto, utilizzando dei costrutti simili alla lingua inglese ed alle formalizzazioni matematiche e logiche, ad ogni singola istruzione corrispondono spesso molte operazioni del processore. Si può similmente parlare di alto livello di astrazione per il fatto che le istruzioni del linguaggio sono distanti dal modo di operare del processore, che di fatto può essere ignorato dal programmatore.L’utilizzo di un linguaggio ad alto livello da parte dei programmatori è possibile perché ad un certo punto avviene una conversione del programma ad un linguaggio a basso livello che il processore può comprendere ed eseguire, detto linguaggio macchina2. Questa operazione può essere effettuata sostanzialmente in due modi.

● Compilazione. Una volta scritto il codice ad alto livello, questo è dato in input ad un programma chiamato compilatore che lo traduce in linguaggio macchina. L’output del compilatore è dunque un programma equivalente al primo che è direttamente eseguibile dal processore. Questo programma è detto anche binario.

● Interpretazione. Il codice ad alto livello può essere direttamente eseguito da un programma chiamato interprete che prende un’istruzione alla volta e la interpreta (la traduce “al volo”) in linguaggio macchina perché il processore la possa eseguire immediatamente. Dunque non dobbiamo aspettare che l’intero codice sia convertito prima di essere eseguito3.

I linguaggi compilati hanno prestazioni migliori dei linguaggi interpretati. Per contro, questi ultimi sono di più facile implementazione e sono anche più portabili, cioè possono più facilmente essere fatti funzionare in processori e sistemi operativi diversi.

1 Il termine implementazione (dall’inglese implement) indica la realizzazione di un algoritmo.2 Un computer moderno è complesso e può essere visto come una pila di macchine di complessità crescente, quindi con vari livelli di linguaggi. Tuttavia, nel mero ambito software distinguiamo solo due livelli: quello più alto del linguaggio di programmazione e quello più basso della macchina.3 Questo è ciò che accade per esempio in un browser, che è un interprete del linguaggio html (usato per rappresentare le pagine in internet): quando apriamo una pagina in internet, cioè quando scarichiamo il suo codice html, cominciamo a visualizzarla prima che sia stato completamente ottenuto il codice.

Cercando di ottenere il meglio di questi due approcci, esistono inoltre linguaggi ibridi, compilati per metà e poi interpretati. Java ne è un esempio4.

Ciclo di vita del softwarePer software si intende l'insieme composto dal programma (o più programmi correlati), in forma di codice sorgente o binario e la sua documentazione (il manuale ed ogni altro documento utile all'utente per l'utilizzo).Il ciclo di vita del software è l'insieme di attività da svolgere per la realizzazione ed il mantenimento del software. I punti fondamentali sono i seguenti.

1. Analisi. In questa fase si valuta la fattibilità del prodotto, si inquadra il dominio del problema e si valutano le risorse necessarie in termini di tecnologie, conoscenze tecniche e costi per la risoluzione del problema. Chi commissiona il software dovrebbe fornire le specifiche del software: un documento dettagliato con i requisiti da soddisfare. Spesso è fondamentale anche lo studio del tipo di utente finale che utilizzerà il software.

2. Progettazione (o design). Questa è la fase creativa della realizzazione del software. Le idee pensate per la risoluzione del problema sono trascritte con diagrammi, tabelle o altre notazioni utili per lo sviluppo. Se la progettazione è buona ed entra nel dettaglio, le fasi successive saranno affrontate meglio e più velocemente.

3. Implementazione (o codifica). L’effettivo sviluppo del programma (o dei programmi) con un linguaggio (o più linguaggi) di programmazione. Nel caso della documentazione questa fase corrisponde alla sua stesura.

4. Collaudo (o test). Valutazione della correttezza rispetto ai requisiti. Un errore rilevato riporterà il flusso dell’attività alla fase 2 o 3.

5. Rilascio. Distribuzione del software al cliente.6. Manutenzione. Modifiche del prodotto per correggere errori o per estendere o

migliorare le funzionalità. Da qui si può ritornare alla fase 1. Nella fase di test, per quanto riguarda i programmi, si parla spesso di debugging cioè dell’eliminazione di bug. I bug (o bachi in italiano) sono malfunzionamenti non voluti dallo sviluppatore di software. Errori di codifica sono detti anche bug di implementazione e sono meno gravi, in genere, rispetto ai bug di design che richiedono di revisionare la progettazione.

4 Il codice Java è tradotto in un linguaggio intermedio chiamato byte code dal compilatore contenuto nel pacchetto Java Development Kit (JDK). Successivamente, un programma chiamato Java Virtual Machine (JVM), contenuto nel pacchetto Java Runtime Environment (JRE), è in grado di interpretarlo. Questo è il motivo per cui per far girare le applicazioni Java è necessario installare JRE (o un plugin che lo contiene).

2. Concetti di base di un linguaggio di programmazione Un linguaggio di programmazione è un linguaggio artificiale e deve essere conforme ad una grammatica al pari di un linguaggio naturale come l’italiano. Infatti, in un programma possiamo osservare caratteristiche sintattiche e semantiche. La sintassi è descrivibile con una serie di regole che deve rispettare il codice per essere accettato dal compilatore. La semantica è il significato del codice, che corrisponde al modo in cui il linguaggio gestisce le informazioni, come i dati e le istruzioni, nella memoria.In questo testo useremo Java. Gli stessi concetti di base, tuttavia, valgono generalmente per molti altri linguaggi come C++ e C# 5.

GrammaticaNei linguaggi di programmazione le regole sintattiche sono molto più rigide che in un linguaggio naturale come l’italiano. Se mettessimo uno spazio o una virgola fuori posto il programma potrebbe funzionare male o non funzionare affatto. Formalizzare una grammatica come quella di Java è molto complesso; qui ci limitiamo a notare che in un programma sono presenti:

● parole chiave (keyword) riservate al linguaggio (import, public, class, void, int, if, else, while ...)

● identificatori, definiti da noi utenti o predefiniti (Ape, maya, direzione, n, accelera, addObject, setX ...)

● espressioni letterali, usate per rappresentare valori costanti di vari tipi (“Ciao”, ‘c’, 42, 3.141592, true, false …)

● simboli operazionali, detti operatori ( + , - , * , / , && , = , != ...)● altri simboli ( , , ; , . , { , ( ...)

5 I linguaggi che condividono i concetti trattati in questo testo sono detti imperativi in quanto i programmi contengono istruzioni che impartiscono ordini agenti sullo stato della memoria. Un’altra classe è quella dei linguaggi dichiarativi (a loro volta divisi tra funzionali e logici), in cui manca il concetto di stato di memoria ed il controllo del flusso è limitato. Si potrebbe dire che nei linguaggi dichiarativi si descrive cosa fare per risolvere un problema, mentre in quelli imperativi si descrive come fare, attraverso una sequenza di istruzioni passo per passo.

Dati Possiamo dire che un programma è composto da dati ed istruzioni, detti anche comandi, per manipolare i dati. In questa sezione parleremo dei dati.

Espressione letteraleCome già introdotto nel paragrafo relativo alla grammatica, le espressioni letterali rappresentano i valori costanti, numerici e non, che scriviamo direttamente nel codice. Ad esempio il numero intero 42, il numero razionale 3.14, la stringa “Ciao”, il carattere ‘c’ o i valori booleani true e false.

VariabileUna variabile è un’associazione tra un identificatore (una sequenza di caratteri che rappresenta il nome della variabile) e la locazione di memoria (una sorta di contenitore che sta in memoria) che ne contiene il valore. Per esempio la variabile direzione potrebbe immagazzinare un valore che rappresenta la direzione di un qualche oggetto in movimento.Solitamente, il valore di una variabile cambia durante l’esecuzione del programma. Tuttavia, per i nostri scopi, considereremo anche le costanti (come il cui valore approssimato potrebbe essere memorizzato in piGreco) come delle variabili.

TipoI linguaggi tipati, come Java, sono linguaggi in cui ogni variabile è associata ad un tipo di dato, o più semplicemente tipo, che rappresenta l’insieme dei valori che può assumere la variabile6. (Di conseguenza i tipi definiscono anche le possibili operazioni che si possono effettuare sulle variabili). Si distinguono principalmente i seguenti tipi. ● Primitivi: tipi semplici che non possono essere decomposti, per esempio boolean, int e

double. Essi sono predefiniti in Java.● Derivati: tipi più complessi costruiti a partire dai tipi primitivi. In Java questi tipi

sono definiti dalle classi, come ad esempio String (classe predefinita in Java per rappresentare le stringhe) o Ape (definita da noi utenti). In questo caso le variabili sono dette anche oggetti.

Di seguito, una presentazione dei tipi primitivi visti finora.

6 Java, in particolare, è un linguaggio fortemente tipato, in quanto le variabili devono necessariamente essere associate ad un tipo.

● boolean rappresenta i valori booleani. Ha due possibili valori: true e false. Internamente, Java li rappresenta con 1 byte di memoria (anche se teoricamente basterebbe un bit).

● int rappresenta i valori interi. Dato che Java rappresenta i dati di questo tipo con 4 byte (32 bit), i valori possibili sono 2³² (circa 4 miliardi), e variano tra -2.147.483.648 e 2.147.483.647. Andare oltre queste cifre provocherebbe un errore.

● double rappresenta i numeri con la virgola. La rappresentazione interna, a 64 bit, è complessa e non ci interessa vederne i limiti.

Comandi che agiscono sui datiDichiarazioneUna variabile, per essere utilizzata deve essere prima dichiarata ed inizializzata. La dichiarazione è una annotazione nella quale si specifica il tipo della variabile e il nome della variabile, cioè la sequenza dei caratteri che la identifica. Questa sequenza dev’essere composta di caratteri alfanumeri (lettere o numeri) più il carattere “_“, con il vincolo che il primo carattere non può essere un numero e il nome non può essere una parola chiave riservata al linguaggio7. Esempi di comandi in Java per la dichiarazione: ● int direzione;● Ape maya;

AssegnamentoL’inizializzazione è il primo assegnamento della variabile ad un valore. Senza un valore non avrebbe senso l’utilizzo della variabile. In Java l’operatore di assegnamento è “=“, a sinistra del quale si pone il nome della variabile, mentre a destra il valore che si vuole assegnare a quella variabile. Il valore può essere un’espressione letterale, cioè una costante, o il risultato di un’espressione da valutare o comando. Esempi:

Comando Effetto successivo all’esecuzione del comando

direzione = 2+1; La locazione di memoria relativa alla variabile direzione contiene i bit che rappresentano il numero 3 (0000 0000 0000 0000 0000 0000 0000 0011), che è il risultato dell’espressione 2+1.

7 La maggior parte dei programmatori seguono lo standard per il quale i nomi delle classi iniziano con la lettera maiuscola ed i nomi delle variabili (oggetti e non) con la lettera minuscola. È bene conformarsi a tale stile.

nome = “Gigi”; (La locazione di) nome contiene (i bit che rappresentano) la stringa di caratteri “Gigi”.

maya = new Ape(); La variabile maya ora fa riferimento all’oggetto di tipo Ape appena creato con l’istruzione new Ape(). Tale comando è descritto in seguito, nel capitolo relativo agli oggetti.

Sebbene in Java i tipi primitivi vengano automaticamente inizializzati ad un valore predefinito (0 per i numeri e false per i booleani), è bene esplicitare sempre questa operazione per rendere più chiaro ciò che stiamo facendo.Successivi assegnamenti delle variabili sovrascrivono con un nuovo valore quello vecchio che quindi sarà perduto.

Altri operatoriGli operatori sono simboli speciali che eseguono qualche operazione. Abbiamo visto che il comando di assegnamento si realizza con l’operatore =. In generale gli operatori usano uno o più operandi e ritornano un risultato. Ad esempio + prende due valori numerici, a sinistra e a destra di esso, e ne calcola la somma. I più comuni operatori sono descritti nella seguente tabella.

Operatore Esempio Significato

= x = 3 Assegnamento

+ 3 + 4 Somma

+ “Ci”+“ao” Concatenazione di stringhe

- 3 - 4 Differenza

- -3 Restituisce il negativo di un numero

* 3 * 4 Moltiplicazione

/ 3 / 4 Divisione

% 7 % 5 Resto della divisione: nell’esempio è 2 (7 : 5 = 1 con resto 2)

++ x++ Utilizza la variabile (se in un’espressione) e poi la incrementa di 1

-- x-- Utilizza la variabile (se in un’espressione) e poi la decrementa di 1

== 3 == 4 Relazione di uguaglianza: restituisce un valore booleano

!= 3 != 4 Relazione di disuguaglianza

> 3 > 4 Relazione “maggiore di”

< 3 < 4 Relazione “minore di”

>= 3 >= 4 Relazione “maggiore o uguale a”

<= 3 <= 4 Relazione “minore o uguale a”

&& b && c Operatore logico “e”: restituisce true sse b e c sono vere

|| b || c Operatore logico “vel”: retituisce false sse b e c sono false

! ! b Operatore logico “non”: nega la verità/falsità di b

Nota: sse sta per “se e solo se”, che indica la reciproca implicazione tra due proposizioni.

ProcedureLe procedure sono piccoli sotto-programmi a cui viene dato un nome (un identificatore) che possono essere richiamati da qualche parte nel codice. Per esempio, può essere utile la procedura accelera, che aumenta la velocità di un’ape, da eseguire ogni volta che l’utente preme il bottone ↑ della tastiera. Come per le variabili, anche le procedure hanno bisogno di una dichiarazione ed una definizione prima di poter essere utilizzate. Per esempio:

public void accelera() // questa è la dichiarazione{

// dentro le parentesi graffe va la definizionevelocita++; // incremento della variabile che rappresenta la velocità

} Per il momento glissiamo sulla sintassi della dichiarazione. Sarà più chiara col tempo.I simboli { e } sono i delimitatori di una specie di contenitore chiamato blocco di codice, utilizzato per strutturare logicamente il codice per vari scopi. In questo caso il blocco contiene la definizione della procedura.Da qualche parte nel codice si potrà chiamare la procedura scrivendo accelera(); (o un comando simile).Spesso le procedure hanno bisogno di informazioni aggiuntive per essere espletate. Ad esempio, se volessimo impostare la velocità di un ape ad un valore ben preciso, potremmo definire la seguente procedura: public void setVelocita(int nuovoValore) // nuovoValore è detto ‘parametro’{

velocita = nuovoValore;} I parametri sono variabili particolari, dichiarate tra parentesi tonde nella dichiarazione, che vivono (sono visibili ed utilizzabili) solo all’interno del loro metodo. Sono inizializzati automaticamente alla chiamata del metodo e sono automaticamente cancellati al termine dell’esecuzione del metodo. Se chiamiamo setVelocita(3); il codice di setVelocita sarà eseguito con il valore 3 assegnato a nuovoValore. Se una procedura necessita di più parametri, questi vanno dichiarati separandoli con una virgola (per es. public void inserisciContatto(String nome, String cognome, int numero)).

FunzioniLe funzioni sono procedure che, allo stesso modo degli operatori, restituiscono un valore al chiamante (la linea di codice che ha fatto la chiamata). Ad esempio potremmo definire la funzione daCelsiusAKelvin che prende come parametro in ingresso un valore double che rappresenta una temperatura in gradi Celsius e ritorna in uscita il corrispondente valore in gradi Kelvin. Sarà necessario:

1. nella dichiarazione specificare il tipo di dato restituito prima del nome della funzione2. nel corpo della definizione restituire il dato con la parola chiave return

public double daCelsiusAKelvin(double gradiCelsius)

{return gradiCelsius + 273.15;

} Ed ecco una possibile chiamata: double temperaturaK = daCelsiusAKelvin(25); Ora risulta chiaro che la parola void (lett. “vuoto”) nelle le procedure precedenti sta a significare che non si restituisce alcun valore.Tornando al paragone con gli operatori, possiamo di fatto vedere questi ultimi come delle funzioni il cui nome è un simbolo e i cui parametri non sono posti tra le parentesi, bensì prima e/o dopo il simbolo.

Comandi che agiscono sul flusso di esecuzioneIl flusso di esecuzione è l’ordine in cui sono eseguite le istruzioni. Normalmente il flusso è sequenziale, cioè segue l’ordine in cui i comandi sono scritti nel programma. Tuttavia ci sono istruzioni che modificano quest’ordine.

Istruzione condizionale: ifL’istruzione condizionale permette di eseguire dei comandi a condizione che una certa espressione booleana sia valutata vera o falsa. Facciamo un esempio: if(n == 0) x = 0; // questa linea di codice è eseguita solo se n è uguale a 0 La condizione, nell’esempio n == 0, deve essere posta tra parentesi tonde. Il comando successivo, nell’esempio x = 0, è eseguito solo se la condizione è verificata.Per eseguire più comandi sotto la stessa condizione è necessario porli all’interno di un blocco di codice.È anche possibile specificare un ramo alternativo da eseguire se la condizione è valutata falsa con la parola chiave else (lett. altrimenti). Ad esempio if(n % 2 == 0){

// Codice per gestire n pari}else{ // Codice per gestire n dispari}

Istruzione iterativa con guardia: whileQuesta istruzione permette di iterare un comando o un blocco di codice fintanto che una condizione booleana, detta guardia, è verificata. Facciamo un esempio. int n = 3;int x = 1;while(n > 0){ // Questo blocco è eseguito fintanto che n è maggiore di 0 x = x*2; n--;} All’inizio dell’istruzione while, n vale 3. La condizione n > 0 è vera, dunque si esegue il codice all’interno del blocco. Tra queste istruzioni n è decrementato di una unità. Al termine dell’esecuzione del blocco si verifica ancora se vale la condizione. Nel caso sia ancora verificata si esegue nuovamente il blocco e così via. Se, al termine di un ciclo la condizione è valutata falsa, allora si esce passando al comando successivo. Esercizio: quanto vale x al termine dell’istruzione? Cosa calcola l’algoritmo?

Istruzione iterativa con contatore: for…[argomento futuro]

3. La programmazione orientata agli oggetti I linguaggi orientati agli oggetti introducono una serie di novità, rispetto a quelli procedurali come Pascal, basate sulla definizione di strutture, dette classi, comprendenti sia dati che istruzioni.

Classi ed oggettiUna classe è una descrizione di una qualche entità in termini di attributi (caratteristiche) e metodi (comportamenti). Le entità descrivibili, o meglio modellabili, da una classe possono essere di qualunque genere, come oggetti concreti (per es. bancomat), animali (per es. api), concetti astratti (per es. strategie per vincere una partita a scacchi). Gli attributi sono spesso associati a quelle caratteristiche esprimibili in linguaggio naturale (come l’italiano) con i sostantivi; ad esempio la classe per modellare le api potrebbe avere come attributi direzione e velocità. I metodi corrispondono invece ai verbi, come vola, vira, succhia il polline…Gli oggetti sono istanze delle classi, cioè esemplari forgiati dalle classi. Da una classe possono essere creati (istanziati) più oggetti, possibilmente differenziati per avere valori di attributi diversi, ma con le stesse definizioni dei metodi. È utile il paragone tra genotipo e classe e quello tra fenotipo ed oggetto. Il fenotipo è l’organismo vivente conforme alla descrizione genotipica. Esistono fenotipi, chiaramente distinti fisicamente, che condividono lo stesso patrimonio genetico: i gemelli.

Definizione di una classeIn Greenfoot, una classe è definita in un file omonimo da un codice con la seguente struttura: public class Ape extends Actor // <- questa è la dichiarazione{ /* Qui, all’interno del blocco di codice, va la definizione con attributi e metodi */} Nella dichiarazione stiamo dicendo che la classe identificata dalla parola “Ape” è di tipo Actor, cioè sarà usata per creare attori che recitano nel mondo. public, class ed extends sono parole chiave riservate a Java. Sorvoliamo sui dettagli. Una definizione completa di Ape è la seguente.

1. public class Ape extends Actor

2. {

3. // Dichiarazioni di variabili d'istanza:

4. // ogni oggetto possiederà una copia di tali attributi

5. int velocita;

6. int direzione;

7.

8. /**

9. * Costruttore dell'ape. Il codice del costruttore

10. * viene eseguito solo una volta per ogni oggetto,11. * alla sua nascita. Qui si inizializza quindi l'ape12. * con i suoi attributi.13. */14. public Ape()15. {16. super(); // questo è fondamentale per la corretta17. // creazione dell'ape, ma per ora non18. // ci interessa capire che cosa faccia19. velocita = 1;20. direzione = 0;21. }22. 23. /**24. * Act - do whatever the Ape wants to do. This method is called whenever25. * the 'Act' or 'Run' button gets pressed in the environment.26. */27. public void act()28. {29. // Add your action code here.30. // Tutto quello che fa l'ape è girarsi e spostarsi in avanti.31. // Di quanto lo specificano gli attributi dell'ape,32. // che sono variabili, e che sono passati come parametri33. // ai metodi turn e move.34. turn(direzione);35. move(velocita);36. }37. 38. /*39. * I prossimi quattro metodi sono pubblici, quindi40. * costituiscono l'"interfaccia" dell'ape. Sono infatti41. * quei metodi accessibili dall'esterno che consentono42. * di cambiare il comportamento dell'ape.43. */44. 45. public void destra()46. {47. // incremento della variabile direzione

48. direzione = direzione + 1;49. }50. public void sinistra()51. {52. // decremento della variabile direzione53. direzione = direzione - 1;54. }55. public void accelera()56. {57. velocita = velocita + 1;58. }59. public void decelera()60. {61. velocita = velocita - 1;62. }63.}

Definizione degli attributi Gli attributi sono le variabili dichiarate all’interno del blocco di codice che delimita la definizione della classe, e questo è il più piccolo blocco che le contiene. Per questo sono detti anche variabili membro, o semplicemente membri. Nell’esempio riportato gli attributi di Ape sono le variabili velocita e direzione. Per come sono dichiarate, esse sono variabili d’istanza in quanto ogni istanza ne possiederà una copia, possibilmente con un valore diverso dalle altre. Dunque potremo avere api con direzioni e velocità diverse. Più avanti vedremo altri tipi di variabili, oltre a quelle d’istanza.

Definizione dei metodiIn Java si chiamano metodi sia le procedure che le funzioni descritte nel capitolo precedente.Ape() è un metodo speciale chiamato costruttore, che è invocato ogni qual volta si crea una nuova istanza della classe: rappresenta la nascita dell’oggetto. Una particolarità del costruttore è che nella sua dichiarazione non è presente il tipo di dato restituito, ma è sottointeso che sia proprio la classe di appartenenza (Ape in questo caso). Di norma, il costruttore è il primo metodo nella classe ad essere definito. act() (in italiano, recita) è il metodo che tutti gli attori devono avere. In esso sono definite le azioni che l’attore deve svolgere. Tutto quello che l’ape fa è girarsi e andare avanti della quantità specificata dalle variabili d’istanza.Gli altri quattro metodi modificano le variabili direzione e velocita andando di conseguenza a modificare anche il modo di recitare.Tutti i metodi visti sono detti metodi d’istanza perché hanno a che fare con le istanze della classe – infatti usano variabili d’istanza. Più avanti sono riportati esempi di utilizzo.

Creazione degli oggettiUna volta definita la classe possiamo creare oggetti appartenenti ad essa. L’oggetto prende vita quando è istanziato, cioè quando si crea (detto più propriamente, si riserva) una locazione di memoria (uno spazio di memoria di un certo numero di byte) dedicata a contenere l’oggetto. Ad esempioApe maya;maya = new Ape();è il codice per creare maya (nella prima linea di codice l’abbiamo dichiarata, come si fa con qualunque variabile). new è una parola chiave riservata a Java per creare un oggetto e Ape() è il nome del metodo costruttore. Abbiamo assegnato una nuova (new) locazione di memoria dedicata alla variabile maya.Il codice per creare e manipolare gli oggetti sta, a meno di casi particolari, al di fuori della definizione della classe. In Greenfoot, il luogo adatto per creare (dare vita) ed utilizzare (far recitare) gli oggetti (attori) è la classe del mondo. Infatti, se partiamo da un mondo vuoto, aggiungiamo qualche oggetto graficamente e poi clicchiamo su Save the world dal menù a tendina che si apre col click destro, noteremo il codice per creare gli oggetti all’interno del metodo costruttore del mondo. In realtà Greenfoot, oltre al codice qui visto, aggiunge una linea del tipo addObject(maya, 139, 126) la cui funzione è inserire l’oggetto appena creato nel mondo (prima esisteva, ma da nessuna parte, o forse in qualche altro mondo parallelo) alle coordinate cartesiane specificate.

Manipolazione degli oggettiAbbiamo detto che i metodi descrivono i comportamenti degli oggetti. Per chiamare un metodo d’istanza su un oggetto si scrive nomeOggetto.nomeMetodo(), ad esempio maya.accelera(). Il punto ., in Java, indica che vogliamo accedere all’interno dell’oggetto per utilizzarne gli attributi o i metodi, descritti nella classe corrispondente.Se i metodi prendono in ingresso dei parametri questi devono essere posti nelle parentesi tonde. Ad esempio, per impostare a 3 la velocità di maya, utilizzando il metodo definito precedentemente, scriveremmo maya.setVelocita(3).