Quando crei una classe, ogni oggetto di quella classe contiene una copia dei suoi campi di istanza (attributi) NON statici;
degli attributi statici invece ne esiste una sola copia per tutti gli oggetti della classe: in senso lato, è come se fossero "variabili globali" per quella classe.
Questa caratteristica si riflette sui metodi statici:
un metodo statico NON è legato a nessun oggetto della classe in cui è definito, in altri termini, NON hanno un parametro implicito.
Attributi statici e metodi statici costituiscono ciò che si chiama CONTESTO STATICO della classe.
Che significa?
Quando hai una classe puoi creare oggetti di quella classe ed invocare metodi legati agli oggetti; supponi di avere una classe
MiaClasse con dentro i metodi
metodoNonStatico() e
metodoStatico(); allora da qualche parte puoi fare un
main() con le istruzioni
C:
MiaClasse a = new MiaClasse(parametri); // costruisce l'oggetto a di classe Miaclasse
a.metodoNonStatico(); // a = parametro implicito di metodoNonStatico()
MiaClasse.metodoStatico(); // non legato all'oggetto a
non legato all'oggetto significa che il metodo statico avrebbe potuto essere invocato anche SENZA creare un oggetto di classe
MiaClasse.
NOTA BENE: è possibile anche la chiamata in modo classico, ma solo perché sintatticamente è legale, in quanto
a è di classe
MiaClasse ma è inutile e sconsigliato
C:
a.metodoStatico(); // LEGALE MA SCONSIGLIATO
Spero che fin qui sia chiaro, andiamo avanti.
Un metodo statico può accedere solo a campi (attributi) statici o ad altri metodi statici, perché?
Perché campi e metodi statici NON sono legati ad oggetti e sono visibili ovunque (salvo restrizioni fatte con private, per esempio) con la sintassi
nomeClasse.nomeCampoStatico oppure
nomeClasse.nomeMetodoStatico.
I metodi statici NON possono accedere ad attributi NON statici (perché questi sono legati agli oggetti) e NON possono usare direttamente i metodi di istanza (cioè i metodi non statici, anch'essi legati ad oggetti), a meno che non lo facciano indirettamente tramite un oggetto.
Veniamo al binding.
Binding = riconoscere correttamente il tipo di una variabile. E' di 2 tipi, statico e dinamico:
- binding dinamico (dynamic binding / late binding) = si usa per tutti i metodi ECCETTO metodi final, metodi privati, metodi statici. In questo tipo di binding il tipo della variabile è calcolato run-time. Il che è ragionevole: se hai una gerarchia di ereditarietà lo stesso metodo fa cose differenti a seconda dell'oggetto a cui si applica. Esempio: un metodo stampaStipendio(), calcola in modo diverso lo stipendio di un dipendente generico e quello di un manager (nota: un manager è anche un dipendente per cui un manager è una specializzazione di un dipendente, ovvero una sottoclasse di dipendente);
- binding statico (static binding / early binding): il tipo delle variabili è riconosciuto in anticipo e stabilito a tempo di compilazione. Poiché i metodi statici non sono legati ad oggetti particolari usano il binding statico.
Non c'è altro da sapere sui metodi statici, serve fare esercizi.