Paola Magillo, Univestita' di Genova, Corso di Interfacce Utente per Informatica, a.a. 2006-2007.

INTRODUZIONE AL LINGUAGGIO JAVA

Java e' un linguaggio orientato ad oggetti / Object-Oriented (OO).

Che significa linguaggio orientato ad oggetti?

In un linguaggio imperativo tradizionale (non O.O.) ci sono:

Esempio:
Il tipo "cerchio" e' un record con due float x ed y per le coordinate del centro ed un floar r per il raggio.
La funzione "area" prende un cerchio e ritorna la sua area.

#include <stdio.h>
typedef struct {  float x; float y; float r;  } Cerchio;
float area(Cerchio c)  {  return c.r*c.r*3.14;  }
void main()
{
  Cerchio c;
  float a;
  c.x = 3.4; c.y = 12.8; c.r = 9.0;
  a = area(c);
  printf("Cerchio di centro %f,%f e raggio %f, area =  %f\n",
         c.x, c.y, c.r, a);  
}

In un linguaggio object oriented:

Esempio:
La classe "cerchio" ha due float x ed y per le coordinate del centro, un floar r per il raggio, ed una funzione "area" che ritorna l'area del cerchio.

class Cerchio
{
  float x;  float y;  float r;
  float area()  {  return r*r*3.14f;  }

  public static void main(String[] args) 
  {
    Cerchio c = new Cerchio();
    c.x = 3.4f; c.y = 12.8f; c.r = 9.0f;
    float a = c.area();
    System.out.println("Cerchio di centro " + c.x + "," + c.y +
                       " e raggio " + c.r + ", area = " + a);
  }
}
Convenzione: in Java i nomi di classe hanno iniziale maiuscola, gli altri nomi iniziale minuscola.

Diversa notazione per chiamare le funzioni. Es. se c e' un cerchio:

Che cosa e' una classe

Una classe e' l'analogo di un tipo ma comprende anche le funzioni che agiscono su quel tipo.
E' come un record dove alcuni campi sono variabili ed altri sono funzioni.

Analogia tra classe e modulo:

Che cosa e' un oggetto

Come si dice "un valore di un tipo" cosi' si dice "un oggetto di una classe".
Si dice che un oggetto e' istanza della sua classe.

Un oggetto ha:

Un oggetto e' la "nobilitazione" di un puntatore. L'identita' di un oggetto e' la locazione di memoria dove stanno scritti i suoi dati. I valori contenuti in questa locazione possono cambiare nel tempo ma la locazione e' sempre la stessa.

Che cosa c'e' in una classe

Abbiamo detto che una classe ha variabili e funzioni. Non tutte le variabili / funzioni hanno la stessa portata...

Di istanza / di classe

In Java variabili e funzioni di classe sono contrassegnate da parola chiave "static".
Esempio: nella classe "cerchio" posso mettere variabile

static float pigreco = 3.14f;
e usarla nella funzione area().
  float area()  {  return r*r*pigreco;  }
Posso renderla una costante (cioe' il suo valore non potra' piu' essere cambiato) premettendo la parola chiave "final":
static final float PIGRECO = 3.14f;
Convenzione: i nomi di costanti sono a lettere tutte maiuscole (come le macro in C).

Pubbliche e private

In java devo ripetere le parole chiave "public" e "private" prima di ogni variabile o funzione. Dove non specificato, si intende "public".

Si dice che una classe "incapsula" lo stato dei suoi oggetti quando tutte le variabili che descrivono lo stato sono private, percio' da fuori si possono leggere ed assegnare solo mediante le funzioni definite nella classe.

Incapsulazione e' utile quando i valori dello stato sono soggetti a vincoli di validita', e quindi e' importante evitare che qualcuno li modifichi in modo incontrollato.

Esempio: il raggio del cerchio non puo' essere negativo.

class Cerchio
{
  float x;  float y;
  private float r;

  public boolean assegnaRaggio(float r0) 
  {
    if (r0<0) return false;
    r = r0;
    return true;
  }
  ...
}
Convenzione: se un nome di variabile o funzione e' formato da piu' parole, le iniziali delle successive sono maiuscole.

Polimorfismo

In linguaggio tradizionale non posso avere funzioni diverse (cioe' con diversi tipi per argomenti e/o risultato) e con nome uguale.
In linguaggio object oriented si puo'. Si chiama "polimorfismo".

Esempio: funzione sul cerchio "assegna centro" che puo' prendere x,y (e lo mette in x,y) oppure niente (e lo mette in 0,0).

  void assegnaCentro(float x0, float y0)  {  x = x0; y = y0;  }
  void assegnaCentro()  {  x = y = 0.0f;  }

Naturalmente posso avere funzioni con stesso nome in classi diverse. E questo non e' polimorfismo (e' come avere campi con stesso nome in tipi record diversi).

Costruttori e distruttori

Una classe ha sempre due funzioni speciali:

Se non definisco costruttore ce n'e' uno di default che inizializza a zero tutte le variabili. Se non definisco distruttore ce n'e' uno di default che non fa nulla. Se metto il mio, quello di default si perde.
Esempio per classe "cerchio":

  Cerchio(float x0, float y0, float r0)  {  x = x0; y = y0; r = r0;  }
  Cerchio()  {  x = y = r = 0.0f;  }

Oggetti e puntatori

In molti linguaggi O.O. incluso Java (ed escluso C++) c'e' garbage collection = gestione automatica di allocazione e deallocazione della memoria dinamica.
Non esistono puntatori, sostituiti da oggetti.

La memoria di un oggetto viene allocata alla sua creazione:

Cerchio c = new Cerchio(...);
e viene deallocata automaticamente quando non e' piu' accessibile attraverso nessuna variabile. Alla deallocazione viene chiamato il distruttore.

Ereditarieta'

Corrisponde all'idea di un tipo che e' raffinamento di un altro tipo, cioe' gli aggiunge qualcosa.

Una sotto-classe raffina / estende / arricchisce una super-classe aggiungendo nuove variabili e/o nuove funzioni, oppure ridefinendo l'implementazione (cioe' sostituendo il body) di funzioni gia' presenti nella super-classe.

Esempio: Classe "cerchio colorato" aggiunge il colore al cerchio. Eredita tutte le altre variabili e funzioni dalla classe "cerchio".

class CerchioColorato extends Cerchio
{
  float red; float green; float blue;
}

Variabili e funzioni oltre che private e pubbliche possono essere protette: le puo' usare solo la classe stessa oppure le sue sottoclassi. In Java parola chiave "protected". Quelle private le puo' usare solo la classe stessa.

Dovunque si puo' usare un oggetto della super-classe si puo' usare anche un oggetto della sottoclasse.
Se Cls2 sottoclasse di Cls1 posso mettere un oggetto di classe Cls2 dentro una variabile di classe Cls1.
Nonostante l'oggetto sia della sotto-classe, finche' sta in variabile della super-classe gli posso applicare solo metodi della super-classe.

Binding

Binding = come viene associata l'implementazione al nome di una funzione, quando questa viene chiamata.

Un oggetto conosce la sua classe. Supponiamo che fun sia una funzione reimplementata nella sotto-classe. Se obj1 e' della super-classe, obj1.fun(...) esegue l'implementazione della super-classe, se obj2 e' della sotto-classe, obj2.fun(...) esegue l'implementazione della sotto-classe.

In Java questo anche se obj2 fosse dentro una variabile dichiarata come super-classe, perche' c'e' binding dinamico!
In C++ no perche' c'e' binding statico, a meno che il programmatore non dichiari espressamente che per fun vuole binding dinamico.

Gerarchie di ereditarieta'

La relazione di super-classe / sotto-classe genera una gerarchia che (se ereditarieta' e' singola) si puo' rappresentare con un albero.

Classi astratte ed interfacce

Esistono classi astratte che non possono avere istanze, ma servono come super-classi in una gerarchia. Possono dichiarare dei metodi senza darne l'implementazione, che sara' data nelle sottoclassi. Non hanno costruttore.

Le interfacce sono come le classi astratte ma dichiarano solo metodi (non variabili) e non danno l'implementazione di nessuno.
Interfaccia descrive il comportamento comune di oggetti di classi diverse.

Esempio: cerchi, quadrati, ... hanno tutti una funzione "disegnami" anche se le rispettive classi non hanno nulla in comune.

interface Disegnabile
{
  public void disegnami();
}

class Cerchio implements Disegnabile
{
  public void disegnami()  {...}
  ...
}

class Quadrato implements Disegnabile
{
  public void disegnami()  {...}
  ...
}

In Java una classe puo estendere una sola super-classe (ereditarieta' singola) ma puo' implementare un numero arbitrario di interfacce.

Sul linguaggio Java

La classe XXX va messa in un file chiamato XXX.java (stesso nome della classe con estensione .java).

Un programma puo' consistere di piu' file (uno per classe). Java rintraccia automaticamente i file che servono, purche' siano nella directory corrente.

Java (a differenza di C++) e' linguaggio totalmente object oriented. A parte i tipi base (int, float, double, boolean, char) tutti gli altri tipi sono classi.

Il "main" e' una funzione in una classe, che deve avere i seguenti parametri:

  public static void main(String[] args)
Posso "eseguire" qualsiasi classe contenga questa funzione.

Java ha una grande libreria di classi predefinite (Java Foundation Classes, JFC), tra cui:

Queste classi sono divise in package, per usare le classi contenute in un package bisogna "importarlo".

Manuale dei package e delle classi predefinite Java disponibile in rete (http://java.sun.com/reference/api/).

Compilare ed eseguire

Java e' linguaggio pensato per generare programmi portabili su piattaforme diverse senza essere ricompilati ("compile once, execute everywhere").

In caso di errori run-time, l'interprete riporta esattamente dove.

Posso eseguire su qualunque macchina sia installato l'interprete anche se non ha il compilatore. In rete (http://java.sun.com/ e in particolare http://java.sun.com/javase/technologies/) sono disponibili per solaris / windows / linux: