JSON e Java, come si semplifica la vita con Gson In questo articolo vedremo come trattare facilmente il formato JSON in Java, attraverso la libreria Gson. Per chi non lo sapesse (tratto da Wikipedia) ecco che cos’è Json: JSON, acronimo di JavaScript Object Notation, è un formato adatto all’interscambio di dati fra applicazioni client-server.[1] È basato sul linguaggio JavaScript Standard ECMA-262 3ª edizione dicembre 1999, ma ne è indipendente. Viene usato in AJAX come alternativa aXML/XSLT.[2] I tipi di dati supportati da questo formato sono: booleani (true e false); interi, reali, virgola mobile; stringhe racchiuse da doppi apici ("); array (sequenze ordinate di valori, separati da virgole e racchiusi in parentesi quadre []); array associativi (sequenze coppie chiave-valore separate da virgole racchiuse in parentesi graffe); null. Uno dei motivi principali per cui JSON ha avuto successo negli ultimi anno è perché permette di trasferire tra diversi dispositivi, che hanno in esecuzione programmi scritti in diversi linguaggi di programmazione, oggetti/informazioni/dati. Grazie all’utilizzo del formato JSON è possibile convertire una variabile string, del testo, in un “oggetto” in Java. Ecco un esempio di un file JSON, che descrive una persona: { "nome": "Mario", "cognome": "Rossi", "nascita": { "giorno": 1, "mese": 1, "anno": 1980 } } Come potete vedere, è davvero facile leggere un file JSON, in quanto la sintassi usata è davvero minimale. Ora vedremo qualche esempio su come usare la libreria Gson per poter convertire un oggetto in un variabile string JSON e il viceversa, ovvero come convertire una string JSON in un oggetto Java. Per facilità di comprensione, useremo un oggetto davvero semplice, una Persona che ha come attributi il nome, cognome e la data di nascita. Ecco la classe Persona.java: package model; public class Persona { private String nome; private String cognome; private Data nascita; public Persona(String nome, String cognome, Data nascita) { super(); this.nome = nome; this.cognome = cognome; this.nascita = nascita; } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public String getCognome() { return cognome; } public void setCognome(String cognome) { this.cognome = cognome; } public Data getNascita() { return nascita; } public void setNascita(Data nascita) { this.nascita = nascita; } @Override public String toString() { return "Persona [nome=" + nome + ", cognome=" + cognome + ", nascita=" + nascita + "]"; } } Ecco la classe Data.java: package model; public class Data { private int giorno; private int mese; private int anno; public Data(int giorno, int mese, int anno) { super(); this.giorno = giorno; this.mese = mese; this.anno = anno; } public int getGiorno() { return giorno; } public void setGiorno(int giorno) { this.giorno = giorno; } public int getMese() { return mese; } public void setMese(int mese) { this.mese = mese; } public int getAnno() { return anno; } public void setAnno(int anno) { this.anno = anno; } @Override public String toString() { return "Data [giorno=" + giorno + ", mese=" + mese + ", anno=" + anno + "]"; } } Ecco il primo test che permette di trasformare un oggetto di tipo Persona in una variabile string e l’operazione inversa: package tests; import com.google.gson.Gson; import model.Data; import model.Persona; public class ObjectToJSON { public static void main(String[] args) { Persona persona = new Persona("Mario", "Rossi", new Data(1, 1, 1980)); Gson gson = new Gson(); String jsonString = gson.toJson(persona); System.out.println(jsonString); Persona object = gson.fromJson(jsonString, Persona.class); System.out.println(object); } } Ed ecco l’output: {"nome":"Mario","cognome":"Rossi","nascita":{"giorno":1,"mese":1,"anno":1980} } Persona [nome=Mario, cognome=Rossi, nascita=Data [giorno=1, mese=1, anno=1980]] Ecco il secondo esempio/test che utilizza una lista di oggetti di tipo Persona, con le solite due operazioni, creazione e conversione: package tests; import java.util.ArrayList; import java.util.List; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import model.Data; import model.Persona; public class ObjectsToJSON { public static void main(String[] args) { Persona persona1 = new Persona("Mario", "Rossi", new Data(1, 1, 1980)); Persona persona2 = new Persona("Giuseppe", "Verdi", new Data(10, 10, 1970)); List<Persona> list = new ArrayList<>(); list.add(persona1); list.add(persona2); Gson gson = new Gson(); String jsonString = gson.toJson(list); System.out.println(jsonString); java.lang.reflect.Type listType = new TypeToken<ArrayList<Persona>>() { }.getType(); System.out.println(gson.fromJson(jsonString, listType).toString()); } } Ed ecco l’output: [{"nome":"Mario","cognome":"Rossi","nascita":{"giorno":1,"mese":1,"anno":1980 }},{"nome":"Giuseppe","cognome":"Verdi","nascita":{"giorno":10,"mese":10,"ann o":1970}}] [Persona [nome=Mario, cognome=Rossi, nascita=Data [giorno=1, mese=1, anno=1980]], Persona [nome=Giuseppe, cognome=Verdi, nascita=Data [giorno=10, mese=10, anno=1970]]] Occorre ricordare, che dal momento che viene usato una libreria esterna dall’ambiante Java, è necessario importarla all’interno del Java Build path. La libreria Gson è facilmente scaricabile da Internet. Conclusione JSON è un formato davvero potente e semplice da usare, perché permette di inviare dati/oggetti tra diversi componenti di un sistema software, con diversi linguaggi di programmazione in gioco. Calcolatrice in Java: esempi di DP In questo articolo vedremo come realizzare una piccola calcolatrice in Java, che ci permetterà di mettere in evidenza alcuni design pattern molto utili quando si programma. java L’idea di questa semplice calcolatrice in Java è quella di poter eseguire la somma delle principali operazioni matematiche, ovvero somma, sottrazione, moltiplicazione e divisione tra due numeri, interi oppure frazionari. Una volta che si inseriscono i due numeri basterà selezionare l’operazione e il button “Calculate” per poter effettuare l’operazione richiesta. Design pattern presenti In questa applicazione Java è possibile trovare i seguenti design pattern: Proxy: serve per poter decidere a run-time il tipo di operazione MVC: serve per separare il modello, il controllo e la vista Strategy: serve per creare un algoritmo in grado di essere facilmente aggiornabile (è possibile aggiungere una nuova operazione e instanziarla in una sola classe) Il principale elemento del codice è l’interfaccia IOperation che permette di facilitare notevolmente la scrittura del codice. Infatti, se una ci pensa qualche secondo, una qualsiasi operazione matematiche, ha in ingresso dei numeri (double in questo caso) e restituisce un risultato. package mathoperation; public interface IOperation { /** * This method allows to calculate the result of the operation * @param p1 * @param p2 */ public void calculate(Double p1, Double p2); /** * This method let the user to retrive the result calculated * @return */ public String getResut(); } Ovviamente ogni operazione avrà un algoritmo diverso, ma questo viene tenuto in considerazione nelle classi concrete che implementano l’interfaccia. Tornando ai DP, perché è necessario usare un Proxy ? L’utilizzo del Proxy serve per poter cambiare facilmente a run-time un oggetto che in questo caso è la nostra operazione matematica. In sostanza, sarebbero richieste troppe modifiche se l’interfaccia grafica dipendesse dalle singole operazione e non dal proxy (se si dovessero aggiungere delle operazioni, sarebbe necessario modificare le classi della grafica). In questo caso, il Proxy viene “inglobato” nel DP MVC; in questo caso il modello è l’operazione matematica, che viene sostituta dalla classe concreta Proxy (che sarebbe il delegato, cioè quel componente a cui viene chiesto qualcosa, un’operazione). E la strategy ? Un aspetto molto importante del codice è aggiungere un’operazione matematica è davvero semplice, questo grazie all’utilizzo della classe OperantionsAvaible: package mathoperation; import java.util.ArrayList; import java.util.HashMap; public class OperationsAvaible { private static OperationsAvaible avaible = new OperationsAvaible(); private ArrayList<IOperation> operations = new ArrayList<>(); private HashMap<IOperation, String> symbolOperations = new HashMap<>(); private OperationsAvaible(){ createList(); setSymbol(); } public void createList(){ operations.add(new Sum()); operations.add(new Subtraction()); operations.add(new Multiplication()); operations.add(new Division()); } public void setSymbol(){ String[] value = {"+","-","*","÷"}; for (int i = 0; i < operations.size(); i++) { symbolOperations.put(operations.get(i), value[i]); } } public ArrayList<IOperation> getOperations() { return operations; } public static OperationsAvaible getAvaible() { return avaible; } public HashMap<IOperation, String> getSymbolOperations() { return symbolOperations; } } Come si può intuire, per poter aggiungere un’operazione è necessario creare la classe concreta che implementa l’interfaccia IOperation ed inserirla nell’ArrayList della classe OperantionsAvaible. Conclusione Dal momento che l’idea del progetto è abbastanza semplice (creare una semplice calcolatrice), è possibile imparare in maniera facile alcuni importanti design pattern in Java, quali il Proxy e il MVC (Model View Controller). Ci sono alcuni metodi importanti, che non sono stati analizzati in profondità. Il più importante tra questi è il metodo public void update() della classe ProxyOperation, che permette di aggiornare il pannello (View), quando viene premuto il Button (del Controller). Il codice completo è possibile scaricarlo da questa repo: https://github.com/jackbell16/Calculator Concetti di base di Java: polimorfismo In questo quinto post, sarà discusso il polimorfismo, uno dei più importanti concetti di base di Java. Il polimorfismo è uno dei concetti la cui definizione è di facile comprensione, ma per capire completamente il concetto e sopratutto per applicarlo correttamente, è necessario del tempo. Ecco una definizione tratta da Wikipedia: In informatica, il termine polimorfismo (dal greco πολυμορφοσ composto dai termini πολυ molto e μορφή forma quindi “avere molte forme”) viene usato in senso generico per riferirsi a espressioni che possono rappresentare valori di diversi tipi (dette espressioni polimorfiche). In un linguaggio non tipizzato, tutte le espressioni sono intrinsecamente polimorfiche. Vantaggi Il polimorfismo per inclusione permette al programma di fare uso di oggetti che espongono una stessa interfaccia, ma implementazioni diverse. Infatti, l’interfaccia del tipo base definisce un contratto generale che sottoclassi diverse possono soddisfare in modi diversi – ma tutti conformi alla specifica comune stabilita dal tipo base. Di conseguenza, la parte del programma che fruisce di questa interfaccia – chiamata in gergo client – tratta in modo omogeneo tutti gli oggetti che forniscono un dato insieme di servizi, a prescindere dalle loro implementazioni interne (presumibilmente diverse tra loro) definite dalle rispettive classi. In virtù di questa possibilità, si può utilizzare lo stesso codice personalizzandone o modificandone anche radicalmente il comportamento, senza doverlo riscrivere, ma semplicemente fornendogli in inputuna differente implementazione del tipo base o dei tipi base. Se usato bene, il polimorfismo permette di avere una struttura ad oggetti estensibile, in quanto si può indurre il client ad invocare nuovi metodi personalizzati includendoli in una classe apposita; resistente, perché eventuali esigenze future nel programma o nella scrittura del codice potranno essere implementate fornendo ad un client già scritto una nuova classe scritta ad hoc. Da queste righe di introduzione del concetto di polimorfismo è intuibile quanto detto in precedenza, riguardo alla difficoltà di comprendere correttamente il suo utilizzo. Si può dire che questo aspetto di Java, permette di rendere più robusto il codice e sopratutto sarà più semplice aggiungere funzionalità aggiuntive. Vediamo un primo esempio: Fattoria package utils; public interface Animale { public void emetteVerso(); } Con questa struttura di codice è possibile aggiungere qualsiasi tipo di animale, basterà che implementi la sua interfaccia e quindi dovrà emettere un verso ! Disegnabile package utils; import java.awt.Graphics; public interface Disegnabile { public void disegna(Graphics graphics); } /** * Questa classe ha la responsabilità di disegnare tutti gli elementi * in un pannello * @author Giacomo */ package utils; import java.awt.Graphics; import java.util.ArrayList; import javax.swing.JPanel; public class Pannello extends JPanel { private static final long serialVersionUID = 1L; private ArrayList<Disegnabile> disegnabili = new ArrayList<>(); public void aggiungiDisegnabile(Disegnabile disegnabile){ disegnabili.add(disegnabile); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); for (int i = 0; i < disegnabili.size(); i++) { disegnabili.get(i).disegna(g); } } } Attraverso l’interfaccia disegnabile, sarà possibile aggiungere al pannello qualsiasi figura geometria, come ad esempio un rombo, quadrato etc… Conclusione Far dipendere i componenti del proprio progetto da Interfaccia, permette di dare robustezza al nostro software e lo rende facilmente gestibile sia per nuove implementazioni, sia per refactoring. I codici presenti in questo post, come del resto tutti quelli delle lezioni precedenti, sono scaricabili dalla repo di Github, all’indirizzo https://github.com/jackbell16/JavaCode Concetti di base di Java: Ereditarietà In questo quarto post dedicato al mondo Java, vedremo il secondo paradigma della programmazione ad oggetti: l’ereditarietà. L’ereditarietà un concetto molto famigliare a noi. Vediamo un semplice esempio a riguardo. Facciamo l’esempio che dobbiamo realizzare un programmare che permette di gestire alcuni dati relativi a persone, in particolare a studente. Una persona può avere i seguenti attributi: Nome Cognome Data di nascita Città di nascita Un metodo che può essere usato in alcuni applicazioni, può essere ad esempio: calcolaEtà() Uno studente, può avere i seguenti attributi: Nome Cognome Data di nascita Città di nascita Matricola Media dei Voti Come metodi può avere: calcolaEtà() mostraMediaVoti() Non notate qualcosa che accomuna queste due “classi” ? Sicuramente ci sono quattro attributi in comune e il metodo in comune è quello che permette di calcolare l’età. Qualora dovessimo scrivere queste due classi separatamente, dovremmo scrivere del “codice duplicato” e questo non va bene, perché eventuali modifiche, richiederebbero di andare alla ricerca del codice in più punti diversi del programma e quando i progetti diventano sempre più grandi, diventa complicata questa procedura ! Dal punto di vista “operativo” l’ereditarietà si implementa con la seguente sintassi: nomeClasseFiglia extends nomeClassePadre Occorre notare che in Java non è supportata l’ereditarietà multipla (cosa possibile in C++). Questa scelta è stata fatta ancora una volta per aumentare la robustezza del linguaggio di casa Oracle. Un esempio relativo a questo programma è possibile trovarlo nella seguente cartella. L’unico metodo che richiede un ulteriore commento riguarda quello del calcolo dell’età: public int getAge(Date date){ if((date.getMonth()>=birth.getMonth() && date.getDay()>=birth.getDay()) || date.getMonth()>birth.getMonth()){ return date.getYear()-birth.getYear(); }else{ return date.getYear()-birth.getYear()-1; } } Il metodo accetta come parametro una data, che può essere quella di oggi e restituisce un intero, che rappresenta l’età della persona. L’if in particolare non è immediato da capire. Facciamo un esempio: oggi è il 14 di Dicembre e prendiamo la mia data di nascita 16 Luglio 1992. Attraverso il primo if, verifico se sia il mese che il giorno sia maggiore della data di nascita, mentre nella seconda condizione, si verifica che il mese della data passata come parametro, sia maggiore del mese di nascita. Se non ci fosse la seconda condizione, io non avrei ancora compiuto gli anni, perché 14>16 ! Ora introduciamo un nuovo tool importante per la programmazione ad oggetti: i diagrammi UML Questi diagrammi permettono di capire subito le relazioni che ci sono tra le varie classi, i metodi e gli attributi di ciascuna di esse. Facciamo ancora un altro esempio sull’ereditarietà. Facciamo l’ipotesi che stiamo lavorando su un programma di geometria, che richiede l’utilizzo della classi rettangolo e triangolo, per il calcolo delle aree. Potremmo erroneamente, applicare così l’ereditarietà: public public public public public } public public public } class final float float float Triangolo { int NUMERO_LATI = 3; lunghezzaLatoUno; lunghezzaLatoDue; lunghezzaLatoTre; class Rettangolo extends Triangolo { final int NUMERO_LATI = 4; float lunghezzaLatoQuattro; ........ Questo codice è corretto ? Per rispondere alla domanda in generale, cioè capire se l’ereditarietà di giusto oppure no, occorre porsi la seguente domanda: nomeClasseFiglia è un nomeClassePadre ? In quest’ultimo caso: un rettangolo è un triangolo ? La risposta è no ovviamente ! Vediamo un po’ come poter ristrutturare il programma. Come primo passo, è necessario usare un concetto importantissimo in Java che prende in nome di astrazione e successivamente di generalizzazione. Con il primo termine, si intende di “l’arte di sapersi concentrare solo sui dettagli veramente essenziali nella descrizione di un’entità”. Mente come generalizzazione, intendiamo il meccanismo con cui due classi con alcune caratteristiche in comuni, possano essere rappresentate da una classe Padre. Il codice dell’esempio relativo ai rettangolo e ai triangolo non è sicuramente uno dei migliori, ma serve come esempio per capire quando l’ereditarietà è utile da usare oppure no. Ecco il diagramma UML del progetto: Conclusione Perché usare l’ereditarietà ? L’ereditarietà serve per rendere il codice più semplice da leggere, più veloce da modificare e sopratutto per EVITARE CODICE DUPLICATO ! Concetti base di Java: incapsulamento Come già anticipato nel primo articolo su Java, i tre principali concetti dei linguaggi ad oggetti verranno trattati singolarmente. In questo articolo vedremo il primo, che prende il nome di incapsulamento. Questo strumento, è uno dei più importanti in Java, perché rende quest’ultimo linguaggio “robusto”. Il bravo programmatore, deve cercare di “nascondere” parte del codice che non vuole che sia modificato dall’utente, per esempio, pur rendendo accessibile a quest’ultimo attraverso altri meccanismi. Ecco un piccolo esempio che chiarisce questo aspetto. La maggior parte delle persone che sta leggendo questo articolo, avrà sicuramente un cellulare. Uno dei principali dispositivi presenti in uno smartphone è sicuramente la batteria, senza la quale non potrebbe funzionare il dispositivo. Chi ha progettato il sistema operativo per il cellulare, avrà sicuramente creato una funzionalità (interfaccia pubblica) con la quale il singolo utente è in grado di capire la percentuale di batteria disponibile. La percentuale della batteria sarebbe possibile anche calcolarla, smontando il dispositivo e utilizzando un tester (facendo la misura della tensione ai capi della batteria). Ma questo potrebbe causare il danneggiamento del dispositivo ! Il principio dell’incapsulamento è molto simile all’esempio precedente. Facciamo ora un esempio software. Facciamo che in un classe di un programma, ci sia del codice che permette di inserire una data. Tutti sanno che non tutti i mesi hanno 31 giorni, inoltre c’è un mese che ne ha 28. Quindi alcune date, come ad esempio 31/9 non sarebbe valido e quindi sono necessari alcuni controlli. Ecco il codice che mostra come non sia vantaggioso l’utilizzo dell’incapsulamento: /** * Questa classe non sfrutta l'incapusalemtno. Dunque non è possibile effettuare controlli sull'inserimento di dati. * @author Giacomo */ package utils; public class DateSenzaIncapsulamento { public int year; public int month; public int day; public DateSenzaIncapsulamento(int year, int month, int day) { super(); this.year = year; this.month = month; this.day = day; } @Override public String toString(){ return day+"-"+month+"-"+year; } public static void main(String[] args) { DateSenzaIncapsulamento dateSenzaIncapsulamento = new DateSenzaIncapsulamento(2013, 9, 31); System.out.println(dateSenzaIncapsulamento); } } A video viene stampata la data che l’utente ha inserito senza nessun controllo. Vediamo come dovrebbe essere la classe Date, con l’utilizzo dell’incapsulamento. Dal punto di vista del codice, questa condizione si trasforma nel rendere tutti gli attributi private e creare dei particolare metodi di tipo public, che permette all’utente di accedervi. Occorre notare che ci possono essere anche dei metodi private e non solo gli attributi. /** * Questa classe permette di instanziare date. Viene ancora una volta mostrato il grande vantaggio che offre * l'incapsulamento, permettendo di fare controlli sui dati inseriti dall'utente. * @author Giacomo */ package utils; public class Date { private int year; private int month; private int day; public Date(int day, int month, int year){ setDay(day); setMonth(month); setYear(year); } public int getDay(){ return day; } public void setDay(int day){ int maxDay=31; switch(month){ case 2: maxDay=28; break; case 4: case 6: case 9: case 11: maxDay=30; break; default: break; } if(day<1){ verificaData(); day=1; }else if(day>maxDay){ verificaData(); day=maxDay; } this.day=day; } public int getMonth(){ return month; } public void setMonth(int month){ if(month<1){ verificaData(); month=1; } else if(month>12){ verificaData(); month=12; } this.month=month; setDay(this.day); } public int getYear(){ return year; } public void setYear(int year){ this.year=year; } public void verificaData(){ System.err.println("Attenzione, vefica il corretto inserimento della data"); } @Override public String toString(){ return getDay()+"-"+getMonth()+"-"+getYear(); } } All’interno di questa cartella condivisa, è possibile trovare tutto il codice che è appena stato descritto. Vediamo di capire un po’ meglio come funziona il codice appena scritto. Gli attributi che vengono inizializzati private rappresentano l’anno, il mese e il giorno di una data. Successivamente viene scritto il costruttore, che non è quello di default, dal momento che vengono inseriti direttamente i 3 valori che rappresentano la data. Inoltre all’interno delle parentesi graffe vengono impostati i 3 valori, attraverso i metodi set. public Date(int day, int month, int year){ setDay(day); setMonth(month); setYear(year); } All’interno dei metodi set, vengono fatti i relativi controlli. Questo permette di aumentare la robustezza del codice appena scritto, evitando che l’utente possa inserire date sbagliate ! Il metodo toString() serve per rappresentare con un certo layout la data inserita. La parola @Override verrà chiarita nella prossima puntata, quando parleremo dell’ereditarietà. Conclusione Come già spiegato nelle righe precedenti, l’incapsulamento permette di aumentare la robustezza del nostro codice, permettendo di accedere in modo controllato ad attributi o metodi. Il codice scritto in questo metodo, oltre che ad una migliore leggibilità, permette di essere utilizzato più volte nel corso del tempo. Eclipse: un ottimo tool per programmare in Java Nella scorsa puntata, abbiamo fatto una breve introduzione al linguaggio di programmazione in Java. Come è stato indicato nel post precedente, per iniziare a programmare basta un normale editor di testo. Questo è sempre vero, ma quando i programmi iniziano a diventare sempre più complessi, con molte classi, il codice da scrivere diventa sempre più grande. Per questo ci viene incontro un ottimo tool di programmazione gratuito, che si chiama Eclipse. Eclipse è disponibile per le principali piattaforme, quali Mac Os, Windows, Linux. Addirittura è possibile installarlo su Raspberry Pi, in modo da poter usare il tool anche su iPad, attraverso un VNC Server. Per procedere all’installazione del software basta andare nella pagina web dedicata ai download http://www.eclipse.org/downloads/ e selezionare il pacchetto dedicato per il proprio sistema operativo. Per quanto riguarda Windows, l’installazione avviene tramite il solito installer, mentre per Mac Os è necessario creare un pacchetto .App, per poter installare correttamente il programma. Per Linux, in particolare per Ubuntu, l’applicazione è disponibile in Ubuntu Software Center. Per le altre distro, basta digitare da terminale: sudo apt-get install Eclipse Per tutti i sistemi operativi, è necessario installare il pacchetto Java dal sito di Oracle, anch’esso gratuito, che in pratica contiene la JVM. Quali sono i principali vantaggi di Eclipse ? Per chi non lo sapesse, Java è considerato un linguaggio semplice, perché se qualcosa viene dimenticato dallo sviluppatore, il compilatore Java è in grado di “capire” eventuali errori. Non vi siete accorti che negli esempi precedenti, non è stato necessario importare alcune libreria ? Questo perché ci ha pensato il compilatore ! Eclipse permette di automatizzare la scrittura di parte del codice attraverso il Content Assist. In pratica se dobbiamo digitato un ciclo for, basterà iniziare a scrivere la lettera f e premere Ctrl+Space ed al resto ci pensa lui ! Altri vantaggi sono la possibilità di capire se ci sono stati degli errori di sintassi del codice. Questo sicuramente facilita la vita del programmatore, che in pratica dovrà “solo” pensare ad organizzare correttamente il codice ! Ecco un esempio che mostra come usare Eclipse. Il programma che stiamo per realizzare non fa altro che sommare i primi N numeri naturali. Per facilitare la creazione di un programma, è conveniente creare dei pacchetti, dove inserire le varie classi. Per esempio abbiamo creato il pacchetto utils, dove inserire la classe “utile” , mentre nel pacchetto tests, verranno scritti i vari tests. /** * Questa classe permette di calcolare la somma dei primi N numeri * @author Giacomo */ package utils; public class SommaPrimiNnumeri { private static int somma = 0; private int N; public SommaPrimiNnumeri() { super(); } public int getN() { return N; } public void setN(int n) { if(n>0){ N = n; }else{ System.out.println("Il valore di N inserito non e' valido"); } } public int calcolaSomma(){ for (int i = 0; i <= getN(); i++) { somma = somma +i; } return somma; } } Il codice di Test01 /** * Questo test permette di testare la classe SommaPrimiNnumeri * @author Giacomo */ package tests; import utils.SommaPrimiNnumeri; public class Test01 { public static void main(String[] args) { SommaPrimiNnumeri nnumeri = new SommaPrimiNnumeri(); nnumeri.setN(10); System.out.println("La somma dei primi "+nnumeri.getN()+" numeri vale "+nnumeri.calcolaSomma()); } } Ecco il video che mostra come è stato “facile” creare questo programma in Java: http://youtu.be/DssaAtV5zFA Per scaricare il Workspace creato, basta aprire il seguente link Introduzione al linguaggio di programmazione Java Oggi inizia una breve panoramica su Java., che ha lo scopo di far conoscere questo potente linguaggio di programmazione agli utenti. Dal momento che il linguaggio presenta tantissime funzionalità, per ora verranno introdotti i concetti basilari di questo linguaggio orientato agli oggetti, che verrano introdotti in tre differenti post: Incapsulamento Ereditarietà Polimorfismo Prima di tutto quando nasce Java ? Esso nasce nei primi anni 90, attraverso il programmatore James Gosling. In quegli anni il linguaggio di programmazione più di moda era C++, che stava spopolando dopo il “mitico” C. Fino a pochi anni fa, Java era gestito dall’azienda Sun, ora essa è stata assorbita da Oracle. Uno dei principali vantaggi di questo linguaggio di programmazione è quello di essere considerato “portabile”, cosa molto richiesta nei giorni d’oggi, a causa della presenza di tantissime piattaforme sul mercato dei PC. In pratica, quando si compila un programma in Java, si creare il “bytecode”, che attraverso la Java Virtual Machine, è possibile eseguirlo su “qualsiasi” piattaforma. Una frase che spiega questo concetto è questo: “Write once, debug anywhere” (“Scrivi una volta, correggi ovunque”) Il termine qualsiasi tra “” è dovuta al fatto che recentemente sono stati introdotti nuovi sistemi embedded, su cui è necessario un lavoro ulteriore per migliorare la portabilità. Ecco una definizione, tratta da Wikipedia, riguardo al termine embedded: In elettronica e informatica, con il termine sistema embedded (generalmente tradotto in italiano con sistema immerso o incorporato) si identificano genericamente tutti quei sistemi elettronici di elaborazione a microprocessore progettati appositamente per una determinata applicazione (special purpose) ovvero non riprogrammabili dall’utente per altri scopi, spesso con una piattaforma hardware ad hoc, integrati nel sistema che controllano ed in grado di gestirne tutte o parte delle funzionalità richieste. Se Java risultata essere un linguaggio che permette di fare tutto, perché si utilizza ancora il C ? Il C è usato tantissimo, ancora oggi, per la scrittura dei driver per periferiche, nella domotica e nella robotica. Questo perché il C è più veloce nell’essere compilato. Una differenza di compilazione era molto evidenti agli inizi degli anni 90, ma dopo più di 20anni di sviluppo Java è migliorato sotto questo punto di vista. Ora introduciamo alcuni concetti basilari: Classi Oggetti Metodi Una clase può essere spiegata come un componente software, in cui sono presenti righe di codice. Per esempio, una classe può contenere degli algoritmi per la risoluzione di un problema, come la somma di Numeri. Inoltre una classe può istanziare oggetti. Per esempio una classe “Persona”, può creare nuovi oggetti, come Mario Rossi etc…. In pratica le clasi fanno da “schema” per costruire oggetti. Per chi conosce già il linguaggio C, le classi possono essere considerate delle struct, in cui vengono dichiari gli attributi. Per esempio una possibile classe Persona, gli attributi sono Nome, Cognome. Gli attributi sono le proprietà che gli oggetti possiedono di una determinata classe. Gli attributi possono essere dichiarati in due modi (in realtà esistono altri meccanismi, ma verrano trattati successivamente): pubblico: visibile anche dall’esterno privato: visibile solo entro la classe Questo tipo di protezione è alla base dell’incapsulamento, ma parleremo un’altra volta di questa importantissima proprietà di Java. Come ultimo concetti, c’è Metodo. Per una più semplice comprensione, si può dire che un metodo è una “sorta” di funzione che abbiamo visto in C. In realtà c’è una certa differenza: in C le funzioni erano scritte per risolvere problemi in modo procedurale, in Java, che è un linguaggio ad oggetti, il meccanismo di programmazione è diverso. Ora che abbiamo introdotto un po’ di concetti su Java, passiamo a programmare. Per ora basta aver installato l’ambiente Java dal sito ufficiale e un semplice editor di testa. Nella prossima puntata, vedremo Eclipse, un potentissimo ambiente di programmazione, che facilità (e non poco) la vita del programmatore. Hello World in Java Come primo programma in Java, useremo il famoso HelloWorld: questo programma non fa altro che stampare a video un saluto. class HelloWorld { public static void main(String[] args) { System.out.println("Hello World"); } } Il codice è molto simile a quello del linguaggio C. Dopo aver creato la classe HelloWorld, che devo avere lo stesso nome del file con estensione .java che abbiamo creato, viene dichiarato il Main, che indispensabile per poter eseguire una classe (più avanti capiremo meglio…) successivamente viene fatta una chiamata alla funzione System.out.println, che sostituisce la printf del C. Ma in questo programma dove sono gli attributi e gli oggetti ? Nel codice precedente non ci sono, dal momento che se ne poteva faremo a meno, ma così facendo non è un programma che contempla la filosofia Java. Nel prossima programma vedremo un’applicazione di oggetti e metodi. /** * Questo programma stampa a video un messaggio, usando i concetti di classe, oggetto, metodo * @author Giacomo Bellazzi * */ public class HelloWorld { private String messaggio; public HelloWorld(String messaggio) { super(); this.messaggio = messaggio; } public String getMessaggio() { return messaggio; } public void setMessaggio(String messaggio) { this.messaggio = messaggio; } public void toPrint(){ System.out.println(getMessaggio()); } public static void main(String[] args) { HelloWorld messaggio = new HelloWorld("Ciao Mondo"); messaggio.toPrint(); HelloWorld messaggio1 = new HelloWorld("Hello World"); messaggio1.toPrint(); } } Cerchiamo di capire un po’ questo linguaggio. Ancora una volta, è necessario creare un file con lo stesso nome della classe. Dopo aver istanziato quest’ultima, viene creato un attributo messaggio, che conterrà una determinata frase. Da notare che gli attributi vengono scritti minuscolo, mentre i nomi delle classi, vengono scritte in maiuscolo. In successione, abbiamo il costruttore. Questo blocco di codice, ha lo scopo di facilitare l’inserimento delle frasi per i vari oggetti “messaggio”. Non a caso, nel main, abbiamo usato la sintassi HelloWorld(nome della classe) messaggio(nome dell’oggetto) = new Helloworld(“frase che vogliamo attribuire all’oggetto”). Questa sintassi permette di creare nuovi oggetti, dalla classe HelloWorld. Nel codice precedente, sono stati creati tre metodi getMessaggio() permette di ottenere il testo del messaggio setMessaggio() permette di creare il testo del messaggio, senza utilizzare il costruttore toPrint() permette di stampare a video la frase dell’oggetto messaggio Nel main, per richiamare i metodi, abbiamo usato la sintassi nomeOggetto.metodo. Da notare la sintassi del nome dei vari metodi (prima parola con lettera minuscola, poi le altri parole con lettere maiuscole. Come ultimo esempio, vediamo un piccolo programma che fa la somma di due numeri: /** * Questo programma calcola la somma di due numeri * @author Giacomo Bellazzi * */ public class DueNumeri { private int a; private int b; public DueNumeri(int a, int b) { super(); this.a = a; this.b = b; } public int getA() { return a; } public void setA(int a) { this.a = a; } public int getB() { return b; } public void setB(int b) { this.b = b; } public int calcolaSomma(){ return a+b; } public void stampaSomma(){ System.out.println(calcolaSomma()); } public static void main(String[] args) { DueNumeri primoNumero = new DueNumeri(10, 5); DueNumeri secondoNumero = new DueNumeri(16, 20); primoNumero.stampaSomma(); secondoNumero.stampaSomma(); } } In questo caso, gli attributi sono a e b, due int che rappresentano il primo e il secondo numero di una coppia di numeri, di cui vogliamo calcolare la somma, attraverso il metodo calcolaSomma(). Questo metodo viene chiamato all’interno dell’altro metodo, stampaSomma(). All’interno del main, abbiamo creato i due oggetti di DueNumeri e abbiamo stampa a video la somma. Tutto facile no ? Per poter compilare un programma Java, occorre digitare da terminale: javac nomeClasse.java java nomeClasse Conclusione Questi semplici programmi, hanno lo scopo di incominciare a capire i concetti basilari alla base di Java, quali Classe, Oggetto, Metodo. Le principali caratteristiche, quali Incapsulamento, Ereditarietà e Polimorfismo verrano trattati in tre differenti post. Codici presenti nel post