Inizialmente la differenza tra Java e il C++, o altri linguaggi orientati agli oggetti, era nel fatto che è che questi ultimi permettevano "anche" di usare gli oggetti, mentre con Java si è obbligati a programmare ad oggetti. Ora, anche grazie a Java, la diffusione il paradigma della programmazione orientata agli oggetti è utilizzato da tutti i linguaggi più usati. Quindi soffermiamoci su alcune caratteristiche della OOP.
Sostanzialmente il modo di programmare è simile ai linguaggi della generazione precedente (ci sono variabili, cicli, etc.), solo che sia i dati, sia le funzioni che li manipolano sono racchiusi in strutture dette classi.
Le classi sono dei "prototipi di oggetti", ovvero sono delle strutture astratte (non troppo vedremo) che possono essere instanziate e quindi creare un oggetto (ma anche più di uno).
La classe definisce tutte le proprietà degli oggetti appartenenti a quella classe, detti attributi, e le funzioni che verranno usate per agire su di essi, detti metodi. Ad esempio è possibile definire una classe delle persone, come segue:
Inizio classe persone Attributo annodinascita Metodo calcolaetà(annoattuale) Fine classe persone
La classe delle persone così definita ha un attributo che è annodinascita che sarà sicuramente un numero intero ed un metodo che in base all'anno attuale passatogli calcola l'età della persona. Usando il formalismo di Java, per definire la classe persone scriveremo:
class persone
{
public int annodinascita; // attributo o proprietà
public int calcolaeta(int annoattuale) // metodo
{
return (annoattuale - annodinascita);
}
}
Come si vede abbiamo dichiarato sia il metodo che l'attributo come public, vedremo tra poco cosa significa, vediamo anche che il corpo della classe è racchiuso tra parentesi graffe ({,}) così anche i metodi. Questo come altri elementi sono molto simili alla sintassi del linguaccio C, per questo motivo la sintassi di Java è tra quelle chiamate "c-like". Per chi non ha familiarità con il C, le parentesi graffe servono a rappresentare blocchi di codice, come il costrutto begin end del Pascal.
La classe avrà un cosiddetto costruttore (o più di uno), che è un metodo particolare che di solito viene utilizzato per inizializzare gli attributi quando viene instanziata la classe in un oggetto, esso è una funzione che non ha nessun tipo di ritorno ed il nome uguale al nome della classe.
Possiamo avere più di un costruttore, ma tutti con lo stesso nome, che poi deve essere proprio quello della classe. Chi è abituato a programmare con linguaggi non orientati agli oggetti troverà tutto questo strano, però è possibile perché Java permette il cosidetto overloading di funzioni, ovvero funzioni con lo stesso nome che hanno parametri diversi (detti in informatica parametri formali) sono diverse, e al momento dell'invocazione viene scelta la funzione in base al parametro (detto parametro attuale). Questo vale per ogni metodo, non solo per i costruttori.
class persone
{
// Proprietà
public int annodinascita;
public String Cognome=new String();
// Costruttori
public persone(int annonascita)
{
this("Non Conosco");
this.annodinascita = annonascita;
}
public persone(String Cognome)
{
this(0);
this.Cognome = Cognome;
}
public persone(int annonascita , String Cognome)
{
annodinascita = annonascita;
this.Cognome = Cognome;
}
// Metodo che calcola l'età del soggetto
public int calcolaeta (int annoattuale)
{
return (annoattuale - annodinascita);
}
}
Le linee che cominciano con il doppio slash (//) sono dei commenti e vengono ignorate dal compilatore. Ci sono altri due tipi di commenti, quelli racchiusi tra /* e */ che permettono di definire commenti su più linee e quelli racchiusi tra /** e */, che permettono sempre di definire commenti su più linee, sono detti commenti di documentazione, essi si devono trovare subito prima la dichiarazione di classi, di membri di classi (attributi o metodi) o costruttori, e vengono inclusi nella eventuale documentazione del codice generata automaticamente.
Nell'esempio vediamo che ci sono tre costruttori, diversi per i parametri formali, che hanno lo stesso nome, vediamo inoltre un nuovo attributo che è Cognome, esso è una stringa, definita come:
public String Cognome = new String();
la parte prima dell'uguale è chiara, lo è meno quella a destra, quel new String() crea un nuovo oggetto della classe String, e ne invoca il costruttore che non ha parametri, questo è il modo standard usato da Java per instanziare gli oggetti di una classe. Non deve sorprendere che il tipo di dato stringa sia una classe, in Java è possibile usare oggetti che rappresentano tutti i tipi di dato del linguaggio, inseriti per completezza del linguaggio, detti involucri che a volte sono molto utili, è però possibile anche usare i valori.
Quindi ad esempio ci troveremo a lavorare sia con interi che con oggetti che rappresentano interi.
Un'ultima cosa che salta all'occhio dall'esempio è che i costruttori hanno volutamente dei parametri che hanno lo stesso nome degli attributi, anche questo è possibile in Java, il quale stabilisce che quando c'è un assegnamento alla sinistra dell'uguale ci deve essere l'attributo, e alla destra il parametro, comunque se non vogliamo confonderci possiamo usare il riferimento this, scrivendo ad esempio this.annodinascita intendiamo l'attributo. this è un riferimento all'oggetto, e nell'esempio lo troviamo anche come invocazione di funzione this(0), in questo caso esso è un riferimento ad un costruttore dell'oggetto, in questo caso chiama il costruttore persone (int annodinascita), con il valore 0. è quindi possibile in un costruttore chiamare un costruttore diverso della classe stessa, a patto che l'invocazione sia la prima istruzione del costruttore e che il costruttore sia diverso da quello attuale.
A questo punto siamo pronti a creare oggetti appartenenti alla classe da noi appena definita, abbiamo tre modi per farlo, perché abbiamo creato tre costruttori.
persone Pietro = new persone(1974);
persone Pietro = new persone("Castellucci");
persone Pietro = new persone(1974,"Castellucci");
Possiamo voler creare un altro oggetto della classe persone:
persone Lina = new persone(1975);
Aquesto punto ho creato due oggetti della classe persone, essi sono in una relazione con la classe detta di inst_of (ovvero "istanza di"), gli oggetti si chiamano Pietro e Lina, è possibile anche copiare i riferimenti degli oggetti, ad esempio è possibile scrivere:
persone Pietro2 = Pietro;
Costruiti gli oggetti ne possiamo invocare i metodi, questo si fa indicando Oggetto.Metodo, ad esempio è possibile invocare i metodi:
Pietro.calcolaeta(2000); Pietro2.calcolaeta(2000); Lina.calcolaeta(2000);
Introduciamo adesso degli attributi e dei metodi particolari, i cosidetti membri statici. Per come abbiamo definito i membri della classe non ci è possibile referenziare direttamente dalla classe attributi e metodi (persone.annodinascita è un errore), questo perché essi lavorano su una istanza della classe, ovvero su un oggetto, però a volte può essere utile scrivere metodi e attributi che possano essere invocati senza dover istanziare l'oggetto, ma direttamente dalla classe, per fare questo occorre dichiararli static, ad esempio:
class TitoliAziendaVattelapesca
{
public static int TassodiInteresse = 3;
public String Proprietario = new String();
public static float InteressiMaturati (int Periodo)
{
return((Periodo * TassodiInteresse )/100)
}
TitoliAziendaVattelapesca(String nome)
{
Proprietario = nome;
}
}
Quindi possiamo decidere di instanziare un oggetto della classe TitoliAziendaVattelapesca solo se ci conviene, ad esempio facendo:
if (TitoliAziendaVattelapesca.InteressiMaturati(12) > 1000) CompraAzioni(10000);
Dove CompraAzioni(int X) è una funzione che instanzia un numero X di TitoliAziendaVattelapesca.
Introduciamo adesso la relazione is_a tra classi, data una classe è possibile creare una nuova classe da questa facendo come si dice in gergo una specializzazione della prima classe. La nuova classe creata è in relazione is_a con la prima. Creata una classe studente dalla classe (detta superclasse) persone, la nuova classe eredita dalla prima tutti i metodi e gli attributi, con la possibilità di definirne dei nuovo o di ridefinirne alcuni, in Java l'estensione di una classe si esplicita con la parola chiave extends.
class studente extends persone
{
int matricola;
// Costruttori
public studente(int annonascita)
{
super(annonascita, "Non Conosco");
}
public studente (String Cognome)
{
super(0, Cognome);
}
public studente(int annonascita, String Cognome)
{
super(annonascita, Cognome);
}
}
Come si vede dall'esempio la classe studente eredita tutti i metodi e gli attrubuti della classe persone, definisce un nuovo attributo matricola e nei suoi costruttori chiama i costruttori della classe persone, con super().
super() può essere, come this, una invocazione di un altro costruttore (tra parentesi vanno i parametri eventuali) o un riferimento alla classe (alla superclasse in questo caso), quindi super.annodinascita rappresenta l'attributo annodinascita della superclasse persone.
Le relazioni is_a e inst_of sono le due relazioni più importanti dei modelli ad oggetti.
Concludiamo con un esempio ed alcune considerazioni per spiegare il significato della parola chiave public che abbiamo introdotto sopra, e di private e protected (attributi e metodi possono essere dichiarati come public, private e protected).
class A
{
public int a;
protected int b;
private int c;
// Suoi medodi, attributi e costruttori
}
class B extends A
{
public float a;
protected float b;
private float c;
// Suoi medodi, attributi e costruttori
}
class C
{
// Suoi medodi, attributi e costruttori
}
Abbiamo definito tre classi, A,B e C, B è definita da A ridefinendone i tre attributi, da interi a reali.
In A, nei suoi costruttori e nei suoi metodi ho libero accesso ai propri attributi di tipo intero, senza limitazioni, ovvero posso scriverli e leggerli a piacimento. In B e C accade lo stesso per i propri attributi, ma vediamo cosa succede per quelli delle altre classi.
Ad esempio in B (in un suo metodo) se scrivo espressioni con a,b e c, scriverò delle espressioni per dei float (in Java è importantissimo il tipo delle espressioni), per referenziare invece gli attributi omonimi di A da cui è ereditata, dobbiamo scrivere come sappiamo, super.a, super.b e super.c (e sono degli interi).
Il nostro compilatore Java non darà problemi per le prime due ma ci darà errore per la terza, questo perché il c di A è private, questo vuol dire che è possibile leggere e scrivere quell'attributo solo all'interno della classe a cui appartiene, ma non è possibile leggerlo e scriverlo da classi estranee o da sottoclassi.
A questo punto mettiamoci in un metodo di C, instanziamo qui un oggetto della classe B (lo chiamo b) e scriviamo le espressioni b.a, b.b e b.c , il nostro compilatore a questo punto ci darà buona solo la prima, questo perché la terza è private ed è quindi visibile solo nella classe di appartenenza e la seconda è protected, questo significa che è visibile solo alla classe di appartenenza e alle sue sottoclassi, e C non è sottoclasse di B.
Sopra ho un po' barato, ovvero ho parlato di atributi di classi e di oggetti come se fossero la stessa cosa, ma in effetti lo sono, solo con la piccola differenza che se accedo all'attributo di una classe
nomeClasse.nomeAttributo
questo sarà sicuramente static, e vi accederò solo in lettura, è in pratica una costante.
Quando instanzierò la classe in un oggetto
nomeClasse nomeOggetto = new nomeClasse(parametri);
accedendo allo stesso attributo dell'oggetto
nomeOggetto,nomeAttributo
accederò allo stesso valore di prima, e non potrò modificarlo (è static). Se cercherò invece di accedere ad un attributo non dichiarato static di una classe avrò ovviamente errore, infatti questo attributo verrà creato al momento della creazione dell'oggetto della classe, ed il più delle volte verrà inizializzato dal costruttore dell'oggetto.
Spero di essere stato abbastanza chiaro nella trattazione dell'argomento, però devo dirvi che i modelli ad oggetti sono piuttosto complicati, ed è impossibile spiegarli in dettaglio in un solo paragrafo, occorrerebbe un corso dedicato interamente a loro. Ovviamente quello che vi ho detto non è tutto sui modelli ad oggetti, ho solo introdotto alcuni concetti che ci basteranno per fare i nostri programmi in Java, se dovessi accorgermi durante il corso di avere tralasciato qualche punto importante per i nostri scopi aprirò volentieri una piccola parentesi.
Utilizzare OSGi in EclipseArticolo di introduzione all'utilizzo di OSGI in ambiente Eclipse |
Jsoup: parsing semplice di HTML5 in javaPresentazione della libreria JSOUP: un parser molto semplice per... |
The Cube: una demo 3D per Android con JMonkeyUn progetto di demo passo-passo per gestire gli eventi 3d di base in... |
Parsing JSON semplice con google GSONBreve ed essenziale introduzione alla libreria di google per la... |
AppFuse: realizzare un'applicazione completa (implementare i servizi)Prosegue la serie per realizzare una app completa con AppFuse.... |
Guida Apache StrutsIl primo e più utilizzato tra i framework MVC del mondo Java,... |
Guida Java SpringScoprire il lightweight container più famoso del mondo Java.... |
Guida Java 6Prendendo le mosse dalla guida Java, già presente su HTML.it,... |
Ogni mese, direttamente nella tua e-mail: articoli, script e guide su Java, Visual Basic, VB.Net ed i più diffusi linguaggi di programmazione.
Iscriviti alla newsletter
|
|
Corso Google AdWords Base25 Giugno 2012 a Milano |
|
|
Corso Google AdWords Base05 Giugno 2012 a Roma |