Java/Classi e oggetti: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
- incipit
Riga 71:
 
È convenzione che i nomi delle classi comincino con la maiuscola, ed è bene rispettare questa prassi, per la leggibilità del codice, anche se non è obbligatoria.
 
== Interfaccia della classe ==
 
Una classe è un '''tipo di dati astratto''' (TDA) definito dal programmatore.
Esattamente come ci sono i tipi primitivi cosi ci sono i TDA del programmatore che si usano in maniera simile, tuttavia, mentre per i primitivi si parla di variabili, per i TDA si parla di oggetti. Inoltre, gli oggetti e i primitivi vengono allocati nella memoria in modalità e posizione diverse (rispettivamente nello heap e nello stack, per chi fosse interessato al lato più tecnico). Guardiamo come si dichiarano e inizializzano.
 
Per dichiarare un intero devo usare l'istruzione:
<source lang=java>int a;</source>
cioè devo dare un nome ad una variabile di tipo intero, quindi con "a" uso un valore intero che dovrò “inizializzare” (specificare).
 
Per dichiarare un oggetto devo usare invece:
NomeDellaClasse B;
cioè devo dare un nome ad un oggetto di tipo NomeDellaClasse, quindi con "B" qui uso un riferimento a un oggetto, che dovrò “inizializzare” (specificare).
 
Non è permesso compilare senza inizializzare gli oggetti dichiarati, si può subito dichiararli e inizializzarli poi in un secondo momento, ma bisogna comunque farlo:
<source lang=java>int a = 10;</source>
userò il valore 10 con il nome “a” realmente e pertanto questo sarà allocato in memoria,
 
<source lang=Java>Nomedellaclasse B = new Nomedellaclasse();</source>
 
userò realmente la classe essendo concretizzata nel suo oggetto, con il nome “B”, pertanto questo è allocato in memoria.
 
Nel primo caso uso un valore, direttamente, nel secondo il riferimento ad un valore.
 
Il riferimento al valore è solo un indirizzo della memoria, che punta al valore reale, ma non è direttamente questo.
Le caratteristiche di base della classe sono all'interno dell'oggetto "B" e tutte le altre sono ottenibili.
Adesso posso ottenere realmente ciò che questa classe consente di fare usando il nome oggetto "B" con la notazione "dot" cioè il punto "." e una chiamata ad un suo elemento, così <tt>NomeOggetto.membrodellaclasse</tt>. Ad esempio posso fare:
 
B.faifrase();
 
Ovvero chiamo un metodo che è scritto in Nomedellaclasse, e la JVM eseguirà realmente ciò che è scritto in questo metodo.
 
<source lang=java>
public class Nomedellaclasse {
 
String soggetto= "egli ";
String verbo= "fa ";
String complemento= "qualcosa";
 
public void faifrase(){
System.out.println(soggetto + verbo + complemento);
}
public static void main(String [] Args){
Nomedellaclasse B= new Nomedellaclasse();
B.faifrase();
// la classe Nomedellaclasse è realizzata e allocata in memoria con l'oggetto "B"
// l'oggetto "B" fa quello che la classe permette di fare con "faifrase()", nel codice è "B.faifrase()".
}
}
</source>
 
Ottengo la scritta "egli fa qualcosa".
 
Ancora..., posso addirittura accedere ai singoli elementi e cambiarli:
B.soggetto= "lui ";
In questo modo
<source lang=java>
public class Nomedellaclasse {
 
String soggetto= "egli ";
String verbo= "fa ";
String complemento= "qualcosa";
 
public void faifrase(){
System.out.println(soggetto + verbo + complemento);
}
public static void main(String [] Args){
Nomedellaclasse B= new Nomedellaclasse();
B.soggetto= "lui"; // quì, in esecuzione, cambio e modifico un membro della classe
B.faifrase();
}
}
</source>
Avrò l'output "Lui fa qualcosa".
 
Vi sono già migliaia di classi preconfezionate già pronte e usabili dal programmatore per la stesura del codice sorgente. Queste classi sono documentate ampiamente ed in modo ordinato dalla Sun con il nome di API nella documentazione del JDK (Java Development Kit). Il programmatore non deve far altro che usare le classi già esistenti ed adattarle ai propri scopi con modalità predefinite come l'ereditarietà.
 
Mediante le classi è possibile e necessario incapsulare, ereditare, ''polimorfizzare'' il codice. Incapsulamento, ereditarietà, polimorfismo, sono le modalità della '''programmazione orientata agli oggetti''' (O.O.P.) che determina la differenza rispetto ai precedenti linguaggi procedurali e strutturati, rendendola più performante in quanto diviene modulare, scalabile, riusabile.
Il programmatore partendo dalle classi standard dei packages può arrivare a specificare proprie classi personali più adatte per l'uso del software previsto. Le classi esistenti sono già ottimizzate e collaudate, consentendo un risparmio di lavoro notevole, è difficile se non impossibile farne a meno, ed è anche fortemente sconsigliato. Occorre verificare e confrontare le API sempre e comunque per scegliere le classi a cui aggangiarsi per la stesura del proprio software.
 
Il programmatore può scrivere le classi ereditando da altre classi, nidificandole, implementando le classi astratte e interfacce.
Per tutte queste pratiche e per il loro uso, vedere [[Java/Ereditarietà| il capitolo sull'ereditarietà]].
 
Queste classi (API) sono davvero numerose e per ordinarle in modo che fossero facilmente usabili sono state raggruppate in insiemi specifici, i package.
 
La classe può essere normale, interna, anonima, astratta, secondaria o derivata.
Gli elementi all'interno della classe e la classe stessa si possono proteggere mediante i modificatori di accesso.
In ogni caso non è possibile dichiarare private o protected una classe altrimenti non potrebbe essere estesa e questo non è possibile nella O.O.P..
'''L'interfaccia pubblica''' è costituita dall'insieme dei membri e dei campi pubblici; nel nostro esempio (Nomedellaclasse) tutti i campi sono pubblici. Vedere[[Java/Modificatori| il capitolo sui modificatori]].
 
== Note ==