Vediamo un introduzione a Java e cominciamo subito creare il nostro primo programmino!

Java è un linguaggio di programmazione completamente orientato agli oggetti : di questo paradigma ho già parlato abbastanza in questo articolo di Introduzione alla programmazione a oggetti. In ogni caso, tratterò l’argomento come se non avessi letto l’altro articolo (anche se forse non così approfonditamente quindi è consigliato leggerlo).

In caso l’avessi già letto, puoi saltare questa prima parte o rileggerla per fissare bene i concetti 🙂

Vediamo quindi i tre pilastri su cui si basa la programmazione orientata agli oggetti (o più semplicemente, OOP):

Il primo pilastro:l’ incapsulamento (o information hiding):

Vuol dire che se prima scrivevamo con delle variabili e campi accessibili, adesso viene incapsulato dentro l’oggetto. Ad esempio, l’ ‘informazione se l’oggetto è acceso o no non è direttamente accessibile all’esterno ma solo attraverso metodi.

Inoltre lo stato di un oggetto è un oggetto esso stesso: ad esempio, una stanza ha oggetti mobili, divano, eccetera. In questo modo, un programma può nascondere la sua complessità mediante la semplicità della OOP.

Per esempio possiamo incapsulare dentro l’oggetto ascensore un codice specifico per effettuare lo spostamento.

E questa è una grande funzionalità della programmazione ad oggetti: senza conoscere il codice, posso riutilizzare più volte lo stesso codice.

Ogni oggetto ha un suo tipo: il tipo viene detto classe; ed ogni oggetto è una istanza di una classe, per esempio: l’ oggetto cattedra è istanza della classe stanza. Ovvero, è un tipo di stanza.

Una classe si identifica dal codice che identifica le funzioni. Tutti gli oggetti di un tipo hanno gli stessi metodi.

Ad esempio:

Oggetto: Macchina

Metodi: Frena, Accellera, Clacson.

Le macchine possono tutti fare queste cose, ma sono diverse fra loro infatti implemento più istanze dello stesso tipo di oggetto.

Il secondo pilastro: l’ereditarietà.

Serve ad evitare di “reinventare la ruota”. Se voglio aggiungere o modificare funzionalità già implementate, senza reimplementare il codice (errore comune a chi non conosce la OOP o non può usarla) utilizzo l’ereditarietà.

Praticamente l’ereditarietà è un concetto che mi permette di riutilizzare codice o parte di codice, senza doverlo riscrivere più volte (simile al concetto di funzione in un certo senso, ma molto più potente).
Ad esempio:
Classe:  Cellulare
Metodi:  chiama, rispondi, inviaSMS

Creata questa classe, realizzerò sottoclassi specifiche che specializzano in dettaglio un metodi e ne realizzano altri, e sono sottoclassi della superclasse.

Ad esempio:

  • Classe: Motorola estende Cellulare
  • Classe: Nokia estende Cellulare
  • Classe: Samsung estende Cellulare
  • Classe: Apple estende Cellulare

In questo modo, ogni marca aggiungerà le funzioni più adatte al proprio telefono. Ad esempio, Samsung userà una interfaccia di tipo Android, mentre Apple di tipo iPhone. E, se necessario, potranno scegliere di implementare diversamente uno o più metodi della superclasse (i metodi sono chiama, rispondi, invia SMS) oppure di lasciarli così.

Quando una classe ne estende un’altra, eredita anche gli attributi. Quindi se Cellulare ha numeroDiTelefono, anche le sottoclassi avranno tale attributo.

Il terzo pilastro: polimorifsmo.

(Poli= molti; morfismo, morfo= forma)
Cambio la forma del’oggetto: il polimorfismo è la possibilità di associare ad un oggetto diverse forme.

Questo pilastro ci permette di associare tipi diversi nello stesso oggetto purchè abbiano una relazione di ereditarietà.

Ad esempio, se creo un gioco aspetterò che il mio utente sceglierà la macchina: intanto posso già creare un oggetto vuoto di tipo Macchina, ed inserirgli un’istanza di una sottoclasse appropriata (es: Mercedes, BMW, ecc).

E’ possibile utilizzare le classi base, senza dover conoscere necessariamente la classe specifica di un oggetto.
Questo ci permette di scrivere codice che non dipende dalla classe specifica:

Riprendendo l’esempio del gioco di macchine, dopo averle posizionate tutte sulla linea di partenza, finito il countdown, tutte le macchine guidate dal computer devono partire. Magari il metodo di accensione non è uguale per tutte, ma noi dobbiamo accenderle tutte. Come facciamo?
Presa la lista di oggetti di tipo Macchina, ci basta un ciclo da cui estraiamo di volta in volta l’elemento n ed eseguiamo il suo metodo “accendi()” senza importarci del tipo vero e proprio (Mercedes, BMW ecc).

Come rendere le donne più interessate ai linguaggi di programmazione. LOL
Come rendere le donne più interessate ai linguaggi di programmazione. LOL

Perchè studiare java

Perchè sfrutta la OOP che è un ottimo paradigma di programmazione flessibile e potente.

Creato da James Gosling e altri informatici di Sun Microsystem (ora Oracle), riasle al 1995 e i suoi precursori sono Smalltalk e C++.

Costruito per essere “sicuro”( vabbè…) , cross-platform e internazionale, viene continuamente aggiornato con nuove feature e librerie.

Diciamo che una delle cose personalmente mi attrae, è la caratteristica Wora: Write Once Run Everywhere. Ovvero, scritto una volta, posso farlo girare su tutto: come i linguaggi interpretati o basati su un codice intermedio (come  java) scritto una volta si può far girare su qualunque piattaforma (Mac, Windows, Linux).

Vediamo quindi perchè studiare il Java: non solo perchè potente e diffuso.

HelloWorld.java

public class HelloWorld //nome del programma, subito dopo class
{
	public static void main(string[], args) //metodo della classe main
	{
		System.out.print("Hello, World"); //Corpo del metodo, ogni riga finisce con ;
		//stampa Hello, World senza andare a capo
		System.out.println(); //stampa una riga nuova
	}
}

Il programma (o meglio: la classe) Java risiede in un file che ha lo stesso nome della classe creata (HelloWorld) con estensione .java (HelloWorld.java)

Anche se creiamo una classe java, la classe risiede in un file con stesso nome della classe con .java con il codice sorgente quì sopra e non può esistere una classe .java senza che contenga la classe con lo stesso nome del file.

Come si crea un programma java

Java non è interpretato come Python infatti per testare il nostro codice dobbiamo, una volta creata  la classe, prima compilare il programma e poi eseguirlo.
Partendo da un IDE o da un editor di testo, creiamo il file con estensione .java .

Poi, lo compiliamo: possiamo usare l’ IDE oppure usiamo da terminale javac nomefile.java che prende in input il programma, e lo compila creando un file .class.
Questo file ora è compilato e contiene codice intermedio, bytecode che è una forma del codice che può essere eseguito sulla Java Virtual Machine (JVM).

Qualcuno potrebbe chiedersi, perchè non accade come con Python che esegue direttamente il codice?
La risposta è: per la portabilità.

Infatti i file .class posso può essere utilizzato su qualsiasi sistema, perchè l’ importante è avere una Java Virtual Machine.

Per eseguirlo, diamo da terminale java nomefile (senza l’estensione .class).
A quel punto, la JVM eseguirà il nostro programma.
Utilizzando un IDE come Eclipse invece, solitamente ci basta un click o poco più per avere il nostro programma temporaneamente compilato per essere poi eseguito.

Tipi di dati di base (o primitivi)

Nella OOP useremo i dati di base come mattoncini per costruire gli altri oggetti.
Si chiamano anche built-in (predefiniti) e sono assolutamente da conoscere e sapere quali sono tipi primitivi e quali non lo sono: i tipi primitivi infatti non sono oggetti.
Li utilizziamo per motivi di efficienza e di memoria, i tipi predefiniti infatti utilizzano meno memoria degli oggetti.

I principali tipi di base sono:
[minimal_table]

In Java si chiama: Tipo: Dimensione:
int interi – es: -1,-2,3,20 4 byte
double Numeri in virgola mobile – es: 3.4, 5.6, -2.3 8 byte
long interi di grandi dimensioni 8 byte
float Numeri in virgola mobile di “piccole” dimensioni 4 byte
boolean Vero o Falso, valore booleano 1 bit
char Per rappresentare caratteri – es: c, a, s 2 byte
String Stringa: una sequenza di caratteri. Non è un vero e proprio tipo primitivo. *

[/minimal_table]

Le variabili

Cominciamo a vedere un argomento fondamentale della programmazione in generale: le variabili.

Prima di vedere come si utilizzano nella pratica, vediamo di definirle nella teoria: una variabile può essere considerata come una specie di scatola dove inserirci un valore( o, più in generale, un oggetto).

La domanda che potrebbe venire subito da chiedersi è: si, ma a che mi serve?

Prima di tutto, la utilizziamo per comodità: metti per esempio che stiamo facendo un programma che ha a che fare con un codice fiscale. E’ molto più facile scrivere “codiceFiscaleFederico” piuttosto di tutto il mio codice fiscale!

In pratica comunque, le variabili sono dei riferimenti a degli oggetti salvati in memoria.  Vediamo quindi un pò come si definisce una variabile.

Intanto, ripetiamo, una variabile è un nome usato per riferirsi a un valore di un tipo di dati (ad esempio: un intero utilizzato per contare).
Una variabile in java deve essere creata mediante una dichiarazione ovvero dobbiamo specificare il tipo:

int contatore;

Il valore viene assegnato a una variabile mediante una assegnazione

contatore = 0

Definizione tipo ed assegnazione può essere anche fatto in una riga:

int contatore = 0

Una volta dichiarato il tipo della variabile è statico e quindi non può essere cambiato (non posso assegnare alla variabile contatore vista poco fa, una lettera).

Inoltre non posso scrivere:

a = 50;

Come per esempio in Python, perciò dovrò fare:

int a; a =50;

Oppure ancora:

int a = 50;

Non posso inoltre scrivere

int a = "stringa;" //stò cercando di assegnare ad un intero una stringa
String a = 60 //stò cercando di assegnare ad una stringa un intero

Il nome di una variabile è detto identificatore: ovvero una sequenza di lettere, cifre, _ e $ la prima delle quali non è una cifra e le cui lettere sono case sensitive. Inoltre, non poissono utilizzate alcune parole riservate.

Esercizio

[blockquote]Crea una variabile miaVariabile di tipo Stringa, assegnale il valore “Ciao, Mondo!” e poi stampala.[/blockquote]

Sapendo che con

 System.out.print(nomeVariabile);

possiamo stampare a video il contenuto di una variabile e che dobbiamo inserire il codice all’interno del metodo main:

class Prova
{
    public static void man(String[] args)
    {
        //Mio Codice
    }
}

[toggle title=”Soluzione”]L’esercizio è praticamente identico al primo progamma di prova, Hello,World, creato nella lezione precedente. Prima di tutto creiamo una nuova classe, che chiamaiamo nel mio caso Prova.

Scriviamo il metodo main, metodo che viene avviato automaticamente dalla JVM quando proviamo una classe, e all’interno di questo:

  • Inizializziamo la variabile miaVariabile con il tipo String e il contenuto richiesto
  • Utilizziamo l’istruzione System.out.print(miaVariabile); per stampare a video il contenuto di miaVariabile.

In pratica:

class Prova
{
    public static void man(String[] args)
    {
        miaVariabile = "Ciao, Mondo!!";
        System.out.print(miaVariabile); 
    }
}

Clicchiamo sul run (o Avvia) per testare il risultato.

[/toggle]

camelCase e Convenzioni

Per i nomi delle variabili per convenzione si utilizza la notazione a cammello (Camel Case).

In base a questa la prima lettera deve essere minuscola, e le inziali delle parole che compongono il nome della variabile devono essere maiuscole. Ad esempio:

iPod, miaVariabile, contatoreMesi, ecc

I nomi delle variabili poi devono avere un nome sensato: è infatti sconsigliato utilizzare

int a; int b; int c;

ma piuttosto:

int contatore; int giorno; int altezza.

Quindi, una corretta assegnazione del nome della variabile potrebbe essere:
Es:
Do_you_like_underscore
Do-you-like-minus:
orMaybeCamelCase

Usare il camel case, vuol dire che avremo un’ iniziale minuscola, e lettere che compongono l’inizio di ogni parola successiva maiuscole: es. contatoreIntero, posizioneX, myInteger.

Assegnazione e inizializzazione

Come già abbiamo visto, possiamo dichiarare una variabile, ed evitare di definire immediatamente il valore:

int a;
a = 20;

In questo caso, l’uguale prende il nome di operatore di assegnamento.

Espressione

Un’ espressione è un letterale , una variabile o una sequenza di operazioni su letterali e/o variabili che producono un valore.

Supponiamo di voler effettuare l’assegnazione:

c= a*2+b

prima esegue l’espressione destra e poi l’assegna alla variabile di sinistra. Per essere sicuri dell’ assegnazione del valore che ci aspettiamo, dobbiamo ricordarci la precedenza degli operatori:

Precedenza degli operatori

*,/,% hanno precedenza, da sinistra verso destra
+, valutati per secondi da sinistra verso destra,
&&, || rispettivamente and e or, hanno meno meno precedenza degli altri operatori.

Gli array

Gli array sono un’altro concetto fondamentale di qualsiasi linguaggio di programmazione che si rispetti: essi ci permettono di definire una lista di oggetti dello stesso tipo.

Per dichiarare un’ array, utilizziamo le parentesi quadre in questo modo:

int[] array;

Possiamo definire la grandezza dell’array senza impostare il contenuto:

array = int[4]

Con questa assegnazione, allochiamo in memoria spazio contiguo sufficiente a contenere 4 interi. Per valorizzare l’array, che con  l’ultima dichiarazione ha allocato spazio per 4 interi e li ha impostati a 0 utilizziamo le parentesi graffe:

array = {1,2,3,4}

La dimensione di questo array è 4 ma si comincia a contare da zero. Questo vuol dire che l’elemento in posizione 1, ha indice 0, quello in posizione 2 ha indice 1 e così via.

Per avere il valore del primo elemento, in questo caso 1, usiamo questa sintassi:

array[0];

Ovvero nome dell’array, e l’indice dell’elemento che vogliamo fra parentesi quadre.

Inoltre, possiamo avere array di qualsiasi tipo: di tipi primitivi, oggetti creati da noi, e anche array di array (chiamati anche array multidimensionali).

Esercizio

[blockquote]Creare un Array di stringhe contente le stringhe: “Hello”, “World”, “Ciao”, “Mondo” e stampare: Hello, Mondo.[/blockquote]

Sapendo che, per concatenare variabili e stringhe, si utilizza il segno dell’addizione +.

[toggle title=”Soluzione”]Creiamo prima di tutto l’array ed inizializziamo con i valori richiesti. Dopodichè, utilizziamo System.out.print per stampare le stringhe e usiamo + per concatenarle:

class Prova
{
    public static void main(String[] args)
    {
        String[] mioArray = {"Hello", "World", "Ciao", "Mondo"};
        System.out.print(mioArray[0] + "," + mioArray[3] + ".");
    }
}

[/toggle]

Come creare un semplice bot in Java

Bot è un termine derivato da robot e sono software più o meno complicati che fanno da robot virtuale: ovvero possiamo chattare col nostro software simulando una persona in modo più avanzato oppure inserire dei comandi.

Esempio:

public class BotSempliceSemplice
{
    public static void main(String[] args)
    {
        System.out.print("Ciao");
        System.out.print(args[0]);
        System.out.println(". Come va?");
    }
}

Il metodo out.print della libreria System ci permette di stampare a video una stringa. Quello che fà la riga dopo la stampa di “Ciao” (senza virgolette) è stampare a video il primo argomento che passiamo in input al programma.

Per mandare in input un valore al metodo main, da Eclipse in alto clicchiamo su Avvia-> Avvia configurazione, e poi nella scheda Argomenti inseriamo gli argomenti per il programma.

Ogni programma di java è strutturato come quest’esempio:

  • In prima riga definiamo il nome dell’oggetto, che deve essere lo stesso del file.
  • Per essere avviato, ha bisogno di un metodo main con quella struttura (public static void)

Di fatto noi vediamo il programma come una scatola nera: ed è in fondo la stessa cosa che fa il compilatore java ovvero prende in input il file java, emette una compilazione, e crea il bytecode.

Bisogna utilizzare uno stile per programmare: posso anche fare a meno di indentare il codice (inserire gli spazi all’inizio della riga), andando a capo ma il codice è fatto per essere letto e riusato da altri (e da noi stessi) e dopo qualche giorno rivedendo il codice se non utilizziamo un certo stile saremo costretti a rileggerci, riga per riga, che cosa fa il programma.

Una cosa ovviamente ostica per un programma da cento righe non ti pare?