Java/Classi e oggetti: differenze tra le versioni

Wikibooks, manuali e libri di testo liberi.
Contenuto cancellato Contenuto aggiunto
→‎Interfaccia pubblica e privata della classe: non esiste una "interfaccia privata"; non esistono "istanze pubbliche", né tantomeno private; non è vero che le classi interagiscono solo tramite l'interfaccia "pubblica"
incollo testo interamente scritto da me, da Java/Concetti preliminari
Riga 11: Riga 11:
Questo è in analogia con i tipi primitivi, per i quali ogni valore rappresenta un dato semplice (es. un numero) su cui sono definite delle operazioni (es. gli operatori aritmetici). Il vantaggio delle classi sui tipi primitivi è che esse permettono la definizione di un numero potenzialmente illimitato di operazioni. Ognuna delle operazioni è chiamata ''metodo'' ed ha un nome alfanumerico ad esso associato.<ref>In realtà il nome da solo non è sufficiente per identificare un metodo: gli elementi che lo identificano sono collettivamente chiamati ''signature'' del metodo e comprendono anche altri elementi. Si veda la [[Java/Oggetti#Overloading|sezione]] sull'overloading dei metodi.</ref>
Questo è in analogia con i tipi primitivi, per i quali ogni valore rappresenta un dato semplice (es. un numero) su cui sono definite delle operazioni (es. gli operatori aritmetici). Il vantaggio delle classi sui tipi primitivi è che esse permettono la definizione di un numero potenzialmente illimitato di operazioni. Ognuna delle operazioni è chiamata ''metodo'' ed ha un nome alfanumerico ad esso associato.<ref>In realtà il nome da solo non è sufficiente per identificare un metodo: gli elementi che lo identificano sono collettivamente chiamati ''signature'' del metodo e comprendono anche altri elementi. Si veda la [[Java/Oggetti#Overloading|sezione]] sull'overloading dei metodi.</ref>


===Sintassi===
=== In altre parole... ===
Il concetto di partenza è che è possibile raggruppare insieme una struttura dati e un insieme di operazioni definite su questa struttura dati. L'insieme viene chiamato "oggetto". La classe non fa altro che stabilire
*come è fatta la struttura dati in questione
*quali sono le operazioni che l'oggetto consente ad altri oggetti di invocare
*l'implementazione di queste operazioni.
Si dice che un oggetto è ''istanza'' di una classe se è quella la classe che definisce la struttura dati e le operazioni che appartengono all'oggetto in questione.

La struttura dati viene definita da un insieme di ''campi'': variabili "di proprietà" dell'oggetto che vengono allocate in memoria quando l'oggetto viene creato e deallocate quando l'oggetto viene ''garbage-collected''. Le operazioni, invece, sono chiamate ''metodi'' e sono costituite da una sequenza di istruzioni che possono eventualmente fare uso dei campi dell'oggetto o anche di altre operazioni definite da quello o da altri oggetti. Si dice che un metodo viene ''chiamato'' o ''invocato'' su un certo oggetto.

Ogni metodo è dotato di una ''signature'': tipo di ritorno, nome del metodo e lista di argomenti. Nella definizione del metodo sono presenti anche altri metadati, ma quelli che distinguono univocamente un metodo tra gli altri di una certa classe (la ''[[w:it:Firma (programmazione)|signature]]'', appunto) sono questi.

Un campo o metodo di una classe può essere ''statico'' o no. Un membro statico si differenzia sintatticamente da uno ''di istanza'' per la presenza della parola-chiave ''static'' nella definizione. Un membro di istanza "appartiene" alle istanze della classe che lo definisce, nel senso che gli altri oggetti del programma chiamano il metodo o usano il campo appartenente alla singola istanza specifica. Un membro statico, invece, non appartiene a un certo oggetto, ma piuttosto alla classe in cui è definito.

La presenza dei membri statici permette di ottenere qualcosa di simile alle [[w:it:variabile globale|variabili globali]] e alle [[w:it:funzione (informatica)|funzioni]] dei linguaggi procedurali, come il C. In alcuni casi i membri statici sono indispensabili, ma farne un uso eccessivo significa allontanarsi dall'aspetto object-oriented del Java ed è sconsigliato. In Java non si parla di ''funzioni'', ma sempre e solo di ''metodi'' (anche quando sono statici).

==Sintassi==
La classe ha lo scopo di delineare le proprietà e le caratteristiche degli elementi che ci servono. Questi elementi possono poi essere creati realmente (''istanziati'') e diventano così “oggetti”: le istanze della classe sono gli oggetti.
La classe ha lo scopo di delineare le proprietà e le caratteristiche degli elementi che ci servono. Questi elementi possono poi essere creati realmente (''istanziati'') e diventano così “oggetti”: le istanze della classe sono gli oggetti.
La classe è un po' come un modello di qualcosa e l'oggetto è questo qualcosa realizzato concretamente. Gli elementi che compongono la classe possono essere: tipi primitivi, metodi, costruttori, oggetti di altre classi, classi stesse. Questi elementi sono tutti racchiusi in un contenitore (la classe) “class”. Vi è quindi la classe e gli oggetti: sono due cose diverse. Grazie all'esistenza delle classi possiamo creare gli oggetti. Gli oggetti sono allocati in memoria dalla JVM.
La classe è un po' come un modello di qualcosa e l'oggetto è questo qualcosa realizzato concretamente. Gli elementi che compongono la classe possono essere: tipi primitivi, metodi, costruttori, oggetti di altre classi, classi stesse. Questi elementi sono tutti racchiusi in un contenitore (la classe) “class”. Vi è quindi la classe e gli oggetti: sono due cose diverse. Grazie all'esistenza delle classi possiamo creare gli oggetti. Gli oggetti sono allocati in memoria dalla JVM.

Versione delle 11:24, 11 mag 2011

Java

Linguaggio Java
Linguaggio Java

categoria · sviluppo · modifica
Come posso contribuire?

→ Vai su Wikiversity

Java:  Guida alla programmazione - Specifica di linguaggioJava/Tipi di dato - Libreria standardJava/Comunicazione seriale


Introduzione:     IntroduzioneJava/Introduzione   •   Procurarsi il JDKJava/Procurarsi il JDK
Il linguaggio:     Dal sorgente all'esecuzioneJava/Dal sorgente all'esecuzione   •   Il linguaggioJava/Il linguaggio   •   Programmazione ad oggettiJava/Programmazione ad oggetti
Aspetti avanzati:     Thread e parallelismoJava/Multithreading   •   Interblocco ricontrollatoJava/Interblocco ricontrollato   •   JavadocJava/Javadoc
Appendici:     EserciziJava/Esercizi   •   La macchina virtualeJava/La macchina virtuale   •   Errori e mitiJava/Errori e mitiTrucchi e consigliJava/Trucchi e consigli


Vediamo uno dei componenti fondamentali dei programmi in Java, la classe.

Introduzione

Una classe è un tipo di dato creato dal programmatore, ed è usata come "stampo" per la creazione di oggetti.

Un oggetto può essere considerato come un insieme di dati (memorizzati nei campi) e di operazioni (definite dai metodi). Ogni oggetto dovrebbe rappresentare un elemento della vita reale e gli aspetti che lo identificano sono raggruppati insieme in un unico punto del programma, cioè la definizione della classe da cui è stato istanziato l'oggetto.

Questo è in analogia con i tipi primitivi, per i quali ogni valore rappresenta un dato semplice (es. un numero) su cui sono definite delle operazioni (es. gli operatori aritmetici). Il vantaggio delle classi sui tipi primitivi è che esse permettono la definizione di un numero potenzialmente illimitato di operazioni. Ognuna delle operazioni è chiamata metodo ed ha un nome alfanumerico ad esso associato.[1]

In altre parole...

Il concetto di partenza è che è possibile raggruppare insieme una struttura dati e un insieme di operazioni definite su questa struttura dati. L'insieme viene chiamato "oggetto". La classe non fa altro che stabilire

  • come è fatta la struttura dati in questione
  • quali sono le operazioni che l'oggetto consente ad altri oggetti di invocare
  • l'implementazione di queste operazioni.

Si dice che un oggetto è istanza di una classe se è quella la classe che definisce la struttura dati e le operazioni che appartengono all'oggetto in questione.

La struttura dati viene definita da un insieme di campi: variabili "di proprietà" dell'oggetto che vengono allocate in memoria quando l'oggetto viene creato e deallocate quando l'oggetto viene garbage-collected. Le operazioni, invece, sono chiamate metodi e sono costituite da una sequenza di istruzioni che possono eventualmente fare uso dei campi dell'oggetto o anche di altre operazioni definite da quello o da altri oggetti. Si dice che un metodo viene chiamato o invocato su un certo oggetto.

Ogni metodo è dotato di una signature: tipo di ritorno, nome del metodo e lista di argomenti. Nella definizione del metodo sono presenti anche altri metadati, ma quelli che distinguono univocamente un metodo tra gli altri di una certa classe (la signature, appunto) sono questi.

Un campo o metodo di una classe può essere statico o no. Un membro statico si differenzia sintatticamente da uno di istanza per la presenza della parola-chiave static nella definizione. Un membro di istanza "appartiene" alle istanze della classe che lo definisce, nel senso che gli altri oggetti del programma chiamano il metodo o usano il campo appartenente alla singola istanza specifica. Un membro statico, invece, non appartiene a un certo oggetto, ma piuttosto alla classe in cui è definito.

La presenza dei membri statici permette di ottenere qualcosa di simile alle variabili globali e alle funzioni dei linguaggi procedurali, come il C. In alcuni casi i membri statici sono indispensabili, ma farne un uso eccessivo significa allontanarsi dall'aspetto object-oriented del Java ed è sconsigliato. In Java non si parla di funzioni, ma sempre e solo di metodi (anche quando sono statici).

Sintassi

La classe ha lo scopo di delineare le proprietà e le caratteristiche degli elementi che ci servono. Questi elementi possono poi essere creati realmente (istanziati) e diventano così “oggetti”: le istanze della classe sono gli oggetti. La classe è un po' come un modello di qualcosa e l'oggetto è questo qualcosa realizzato concretamente. Gli elementi che compongono la classe possono essere: tipi primitivi, metodi, costruttori, oggetti di altre classi, classi stesse. Questi elementi sono tutti racchiusi in un contenitore (la classe) “class”. Vi è quindi la classe e gli oggetti: sono due cose diverse. Grazie all'esistenza delle classi possiamo creare gli oggetti. Gli oggetti sono allocati in memoria dalla JVM.

Per esempio, Mario è un'istanza della classe Dipendente, ossia un oggetto di tipo Dipendente.

Per creare una classe devo usare la parola chiave class con questa sintassi:

public class Esempio {
/*
variabili e costanti...
metodi e costruttori...
cicli e controlli di flusso...
oggetti di classi e classi stesse...
*/
}

la classe Dipendente potrebbe essere


public class Dipendente {
    public int stipendio;
    public String valuta;
    public String nome, cognome;
    public void promuovi() {
     //promuovo il dipendente aumentando del 10% lo stipendio
        this.stipendio=this.stipendio*(1.1);
    }
}

Si noti che dentro la classe abbiamo definito delle variabili che rappresentano le caratteristiche (dette attributi) di un dipendente.

Si riporta l'esempio funzionante del capitolo "Primo programma" della classe HelloWorld:

public class HelloWorld {
    public static void main (String args[]) {
        System.out.println("Hello, world!");
    }
}

È 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:

int a;

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:

int a = 10;

userò il valore 10 con il nome “a” realmente e pertanto questo sarà allocato in memoria,

Nomedellaclasse B = new Nomedellaclasse();

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ì NomeOggetto.membrodellaclasse. 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.

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()".
 
    }
}

Ottengo la scritta "egli fa qualcosa".

Ancora..., posso addirittura accedere ai singoli elementi e cambiarli:

B.soggetto= "lui ";

In questo modo

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();
 
    }
}

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 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 il capitolo sui modificatori.

Note

  1. In realtà il nome da solo non è sufficiente per identificare un metodo: gli elementi che lo identificano sono collettivamente chiamati signature del metodo e comprendono anche altri elementi. Si veda la sezione sull'overloading dei metodi.