1. Il linguaggio Java

Programmazione orientata ad oggetti

Per realizzare delle applicazioni vengono assegnati compiti specifici e parti da realizzare ai vari programmatori.

Ex. In seguito, Alberto è in carica della struttura dati, mentre Bruno è in carica delle operazioni eseguite dall’utente finale.

// Codice di Alberto
typedef struct{
	int day;
	int month;
	int year;
} Date;

void printDate(Date d) {
	printf("%d", d.day);
	if (d.month == 1)
		printf("Gen");
	else if //...
	printf("%d", d.year);
}

// Codice di Bruno
Date data;
// ...
data.day = 14;
data.month = 3;
data.year = 1908;
// ...
if (data.day == 27)
	payWages();

Alberto decide in seguito di cambiare la rappresentazione della variabile mese nella struttura dati in char month[4]. Il codice di Bruno deve essere quindi cambiato, affinché funzioni di nuovo.

Da qui si deduce che ogni volta che Alberto cambia la struttura dati, tocca modificare opportunamente il codice di Bruno, aprendo la possibilità ad errori, spreco di tempo e risorse.

Il problema può essere risolto facendo in modo che Bruno non possa più accedere direttamente alla struttura dati: ad esempio Bruno non potrà più scrivere d.month = 12.

Però a questo punto serve qualcosa che permetta a Bruno di accedere alla struttura dati, anche se non direttamente… Alberto dovrà mettere a disposizione di Bruno delle funzioni base che permettono di eseguire le varie operazioni di cui Bruno ha bisogno sulla struttura dati.

Se Alberto decide di cambiare di nuovo il suo codice, deve cambiare le operazioni che le varie funzioni fornite a Bruno eseguono, ma deve lasciare il prototipo intatto.

Abbiamo incapsulato la struttura dati: ogni cambiamento alla struttura dati rimane confinato nella struttura stessa, cosicché i cambiamenti sono più facili, veloci e meno costosi.

Abstract Data Type

È un’astrazione fatta su dati, che non classifica i dati secondo la loro rappresentazione (implementazione), ma in base al loro comportamento atteso (specifica).

Il comportamento dei dati è espresso in termini di un insieme di operazioni applicabili a quel dato specifico (interfaccia).

Un ADT incapsula tutte le operazioni che manipolano la struttura:

Le operazioni dell’interfaccia sono le uniche che possono essere usate per creare, modificare ed accedere agli oggetti.

Il linguaggio Java

Dato che il linguaggio C non ha una definizione diretta degli strumenti necessari ad operare con gli ADT,

useremo il linguaggio Java.

Caratteristiche del Java

Struttura di un programma Java

Un programma Java è organizzato in un insieme di classi: ogni classe corrisponde ad una dichiarazione di tipo.

Una classe contiene la dichiarazione di variabili, dette attributi, e funzioni, dette metodi:

Il programma principale consiste in una classe chiamata main.

Hello World

public class HelloWorld() {
	public static void Main(String args[]) {
		System.out.println("Hello World");
	}
}

Esempio di classe in Java

public class Date{
	int day;
	int month;
	int year;

	// returns the day
	public int readDay(){...}
	//...
}

I dati e le funzioni sono incapsulati.

Gli attributi di una classe possono anche essere chiamati come variabili di istanza.

I metodi definiscono il comportamento di un oggetto appartenente ad una classe: sono procedure che appartengono agli oggetti e hanno un parametro implicito che indica l’oggetto al quale appartengono (this).

Oggetti

Tutti gli oggetti di una stessa classe hanno la stessa struttura: il numero e il tipo degli attributi è lo stesso.

Ogni oggetto, in ogni istante dell’esecuzione di un programma, è caratterizzato da uno stato, che è determinato dagli attributi dell’oggetto.

Accesso agli attributi e ai metodi

Avviene con la “notazione punto”:

Ex.

Date d;
int x;
// Codice che inizializza d
x = d.readDay();

Cambiamento di stato

Lo stato degli oggetti può cambiare con l’invocazione di metodi che li modificano.

Nella scrittura di un metodo non è necessario usare la notazione punto per riferirsi ad un attributo di un oggetto definito dalla classe, ma si può citarlo direttamente.

Ci sono alcuni casi nei quali non è possibile cambiare lo stato di un oggetto, che viene definito immutabile.

Variabili e tipi di dato

Tipi di dato primitivi

Valori di default

Tipi referenziati

Le variabili di tipo primitivo (int, char, bool) contengono direttamente il valore. Tutti gli altri tipi di variabili (array, enumerazioni, classi ed interfacce) contengono riferimenti al valore: ogni variabile dichiarata da una classe contiene un riferimento ad un oggetto, che consiste in un indirizzo di memoria.

Il valore dell’indirizzo di memoria contenuto nella variabile non è direttamente accessibile al programmatore e non è utile.

Un oggetto è immagazzinato in un’appropriata area di memoria e ogni variabile di tipo oggetto contiene l’indirizzo alla prima cella dell’oggetto in memoria.

Le variabili consentono l’accesso agli oggetti, sono allocate sulla stack e vengono deallocate una volta che il metodo termina, mentre gli oggetti sono allocati sullo heap.

Dichiarazione ed inizializzazione

La dichiarazione di una variabile di tipo referenziato non alloca in memoria lo spazio per rappresentare l’oggetto, ma solo quello per riferirsi ad esso.

Una volta dichiarata, viene automaticamente inizializzata con il valore null.

New

La costruzione di un oggetto viene eseguita dinamicamente attraverso l’operatore new.

Ex. Date d = new Date();

Effetti di new:

Dichiarazione e creazione

Date data;

data = new Date();

data = new Date();

Facendo così il riferimento al primo oggetto è perso: l’oggetto non è più raggiungibile in alcun modo.

Esso verrà distrutto dal garbage collector.

Creazione e distruzione di oggetti

Se la sua implementazione è privata, l’unico modo di inizializzare un oggetto è specificare uno o più metodi speciali, chiamati costruttori.

La creazione di un oggetto con il token new coinvolge sempre l’invocazione di un costruttore.

Il costruttore fa due operazioni base: alloca la memoria necessaria per contenere l’oggetto e inizializza lo spazio allocato con dei valori particolari.

A differenza del C, non è necessario deallocare gli oggetti, che vengono automaticamente distrutti una volta che il garbage collector capisce che non vengono più usati da nessuno.