Classi ed oggetti

Java™ è un linguaggio di programmazione integralmente basato sulla definizione di classi.

Una classe è la descrizione generale delle caratteristiche e delle modalità di elaborazione comuni a tutta una categoria di unità di informazione.

Le singole particolari unità di informazione che godono di tutti gli attributi specificati in una classe sono dette oggetti di quella classe.

Un oggetto è una particolare esemplificazione (ingl. 'instance') di tutte le caratteristiche definite nella classe che lo genera.

Le nozioni di classe e oggetto, in informatica, corrispondono, grosso modo, alle nozioni 'stampo' e 'pezzo' in certi processi industriali. Se si deve produrre un pezzo, prima si costruisce uno stampo da cui, con fusioni o pressioni, si ottiene un pezzo. Ma lo stesso stampo potrà essere reimpiegato nella produzione di molti altri pezzi identici. I pezzi sono realizzazioni concrete del progetto in base al quale è stato costruito lo stampo.
Allo stesso modo in Java, prima di poter utilizzare il complesso di informazioni attinenti ad una specifica entità, bisogna progettarne la classe e poi da essa produrre uno o più oggetti.

Le classi di Java hanno però un vantaggio rispetto agli stampi: possono generare altre classi che ne ereditano tutte le caratteristiche aggiungendone eventualmente di ulteriori.

La piattaforma Java, una volta installata, mette a disposizione del programmatore un sistema di classi predefinite. Il programmatore le può importare. e usare così come sono o ne può raffinare le caratteristiche deducendo da esse nuove classi più adatte ai suoi scopi.


Descrizione di una classe

Una classe è individuata dal suo identificatore ed è descritta da un blocco (il suo corpo)

Il corpo, in linea di massima, comprende due tipologie di elementi, detti membri della classe:

relativi alla categoria di entità rappresentata.

I campi rappresentano caratteristiche qualitative o quantitative di tutti gli oggetti della categoria rappresentata dalla classe: (ad esempio, per una persona: nome, cognome, sesso, età, reddito, ecc.)

Per ogni campo vanno specificati

Ad ogni campo può essere assegnato un valore.

I campi statici (o proprietà) sono specifici della classe, uguali per tutti gli oggetti desunti dalla classe; i campi dinamici sono specifici degli oggetti. Per default un campo è dinamico. Per dichiararlo statico, alla specificazione di tipo va premessa l'indicazione static.

Il tipo definisce il modo con cui va codificata (in memoria o su altro supporto hardware) un valore, e può essere


Tipi primitivi

I tipi primitivi sono codificati in un numero prefissato di byte.

I tipi primitivi di Java™ sono

 

tipo descrizione formato
interi
byte intero da 1 byte 8 bit
short intero da 2 bytes 16 bit
int intero da 4 bytes 32 bit
long intero da 8 bytes 64 bit
reali
float singola precisione 32 bit (IEEE 754)
double doppia precisione 64 bit (IEEE 754)
altri tipi
char carattere 16 bit (Unicode)
boolean logico true o false


Alle variabili di tipo primitivo può essere attribuito immediatamente un valore (ovviamente adeguato al tipo), come nei linguaggi tradizionali.

L'operatore di assegnazione di valore è il segno di uguaglianza '='.

I valori matematici vanno scritti con le usuali convenzioni informatiche.

Negli esempi proposti in seguito si usano commenti, cioè frasi che non appartengono al codice eseguibile, utili ai programmatori per spiegare le modalità di elaborazione.

Esempio: 
//tipo: int; identificatore: dieci; valore: 10
  int dieci = 10;
//tipo: float; identificatore: p_circa; valore: 3.14
  float pi_circa = 3.14;
//tipo: double; identificatore: c_elettrone; valore: 1.6 per 10 elevato a -19
  double c_elettrone = 1.6e-19;

I valori dei caratteri (char), costituiti da un unica lettera o cifra, vanno tra apici.

Esempio:
//tipo: char; identificatore: a_min; valore: 'a'
  char a_min = 'a';
//tipo: char; identificatore: a_mai; valore: 'A'
  char a_mai = 'A';

E' possibile dichiarare una lista di variabili tutte dello stesso tipo.

Esempio:
/*
  tipo: char; prima variabile: a_min; valore: 'a'
              sec.  variabile: b_min; valore: 'b'
              terza variabile: z_mai, valore: 'Z';
*/
  char a_min = 'a', b_min='b', z_mai='Z';
/*
  tipo: double; prima variabile: c_elettr; valore: 1.6e-19
                sec.  variabile: m_elettr; valore: 9.11e-31
*/
  double c_elettr = 1.6e-19, m_elettrone=9.11e-31;
/*
  variabili booleane: simpatico e bello non sono inizializzate ad un valore;
  potranno essere inizializzate in seguito;
*/
  boolean simpatico, bello, ricco=false;

Una volta dichiarato il tipo di una variabile, il suo valore può essere aggiornato con una nuova assegnazione, senza rispecificarne il tipo.

Esempio:
  char car;
  car = 'a';
  ..............
  car = 'A';

Se si vuole che una variabile non cambi mai il valore che le è inizialmente assegnato, cioè che in effetti sia una costante, al tipo va premessa la specificazione final.

Esempio:
  final double c_elettr = 1.6e-19;
  final double m_elettrone=9.11e-31;

 


Classe String

Gli oggetti di classe String in Java™ assumono valori costituiti da sequenze di caratteri stampabili (lettere, numeri, segni vari) ormai indicate solitamente con il termine 'stringhe'. Dato l'utilizzo frequentissimo di questi oggetti in Java è possibile trattarli quasi fossero di tipo primitivo. Oltre ad inizializzarli seguendo la sintassi generale per gli oggetti, cioè con l'uso dell'operatore new, è possibile (anzi è la norma) inizializzarli direttamente come se la classe String fosse un tipo primitivo.

I valori degli oggetti di tipo String sono costituiti da sequenze di qualunque lunghezza di caratteri alfanumerici contenuti tra virgolette doppie (come in C, non tra apici come in Pascal).

Esempio:
  String nome, cognome;
//inizializzazione
  nome = "Gioacchino";
  cognome = "Rossini";
//invece di 
  nome = new String("Gioacchino");
  cognome = new String("Rossini");

La classe String ha comunque molti altri costruttori ed è dotata di molti metodi per la elaborazione delle stringhe.

Due o più stringhe possono essere concatenate con l'operatore + formando un unica stringa.

Esempio:
  String nome= "Gioacchino", cognome= "Rossini";
  String musicista = nome+" "+cognome;

 


Metodi

I metodi (o funzioni) descrivono le elaborazioni che tutti gli oggetti di una determinata classe possono compiere sui loro campi.

Un metodo è descritto obbligatoriamente dal suo tipo, dal suo identificatore seguito da una coppia di parentesi tonde eventualmente contenenti i parametri ad esso trasmessi per l'elaborazione e dal suo corpo contenuto tra parentesi graffe.

Il corpo contiene le istruzioni da eseguire sui campi, parametri o variabili locali.

Se un metodo, al termine dell'elaborazione, produce un risultato di un certo tipo, l'identificatore va preceduto dal nome del tipo del risultato prodotto (classe o primitivo). In questo caso prima del termine dell'elaborazione è necessario che venga eseguita un'istruzione che comunichi all'esterno il risultato prodotto dal metodo: l'istruzione che produce questo effetto è return seguita dal risultato.

Se un metodo svolge elaborazione ma non produce risultati, l'identificatore va preceduto dall'indicazione void e l'istruzione return non è necessaria.

I metodi più importanti di una classe sono i suoi costruttori, cioè i metodi che generano nuovi oggetti della classe stessa. Una classe può avere più costruttori, a seconda delle particolari modalità di generazione di un oggetto.

Possono comunque essere definiti molti altri metodi specifici per elaborare informazioni e produrre risultati.

 


Per applicare alcuni dei concetti più significativi sopra illustrati, provare a realizzare la seguente applicazione.

import java.util.GregorianCalendar;     //si importa la classe GregorianCalendar del package util

public class Data
{
  public Data() //costruttore della classe
    {
      GregorianCalendar oggi = new GregorianCalendar();      // generazione dell'oggetto 'oggi'
      int giorno = oggi.get(GregorianCalendar.DAY_OF_MONTH);     // il metodo 'get' ha per argomento 
                                                            // il campo statico DAY_OF_MONTH 
                                                            // della classe GregorianCalendar
      int mese = 1+oggi.get(GregorianCalendar.MONTH);
      int anno = oggi.get(GregorianCalendar.YEAR);
      String data = "Oggi: "+giorno+"/"+mese+"/"+anno;    // si assegna un valore al campo 'data' 
                                                  // concatenando la stringa "Oggi: " 
                                                  // con i valori dei tre campi
      System.out.println(data);
    }

  public static void main(String[] args)
    {
      Data d = new Data();
    }
}

fig01.gif

Il risultato, a prima vista, può apparire sproporzionato all'impegno richiesto. Ma è un'impressione sbagliata. L'applicazione prodotta è dinamica. Se viene rilanciata domani o dopo, il risultato sarà diverso.