Nella
programmazione orientata agli oggetti
, un
metodo
(o anche "funzione membro") e una una
funzione
associata in modo esclusivo ad una
classe
e che costituisce un'operazione eseguibile sulla sua
istanza
o sul suo tipo.
Come in una procedura di un
linguaggio di programmazione procedurale
, un metodo solitamente consiste di:
- una
firma
(
signature
) ovvero la definizione/dichiarazione del metodo con
tipo di ritorno
,
nome
del metodo, tipo e nome degli eventuali
parametri
passati in
input
(detti
parametri formali
); in genere dunque la definizione di un metodo usa la stessa sintassi impiegata per le procedure (nei linguaggi object-oriented che le supportano), con alcuni indicatori aggiuntivi che consentono di ottenere l'
incapsulamento
delle informazioni.
- il
corpo
del metodo, opportunamente delimitato da inizio e fine, con all'interno una o piu sequenze o blocchi di
istruzioni
scritte per eseguire una determinata azione eventualmente attraverso
strutture di controllo
del flusso di esecuzione quali
selezioni
/controllo e
iterazione
/cicli e sulla base dei parametri passati in
input
, in grado di restituire al programma chiamante un valore di ritorno (o di
output
) dello stesso tipo di quello dichiarato nella firma iniziale. Inoltre, nei linguaggi che dispongono di un meccanismo di
gestione delle eccezioni
, il blocco del metodo puo terminare sollevando un'
eccezione
nel caso si verifichi una situazione anomala che impedisce il corretto completamento delle sue operazioni.
Una delle operazioni che possono essere eseguite da un metodo e la lettura/scrittura di dati "privati" memorizzati in un oggetto o in una classe: in questo modo il
programmatore
puo gestire in modo flessibile l'accesso ai dati, prevedendo, ove necessario, opportuni meccanismi di protezione e validazione.
Le differenze fra il concetto generale di sottoprogramma e quello di metodo derivano dal fatto che il metodo viene interpretato come un'operazione eseguita da un oggetto. Per riferirsi all'invocazione di un metodo si usano talvolta locuzioni che rendono piu esplicito questo legame; si parla per esempio di
dare un comando a un oggetto
o anche
spedire un messaggio a un oggetto
.
[N 1]
Molti linguaggi supportano inoltre le tecniche di
overloading
e/o
overriding
dei metodi.
Un esempio generico in
Java
e il seguente:
//firma o dichiarazione del metodo
public
tipo_ritorno <nome_Metodo> (tipo_parametro1 param1, ... , tipo_parametroN paramN){
//segue corpo del metodo
...
blocco_istruzioni
;
...
if
(condizione logica){
...
blocco_istruzioni
;
...
}
else if
{
...
blocco_istruzioni
;
...
}
else
{
...
blocco_istruzioni
;
...
}
...
blocco_istruzioni
;
...
for
(int i=0; i<10; i++){
...
blocco_istruzioni
;
...
}
...
blocco_istruzioni
;
...
return
<oggetto_tipo_metodo>;
}
Da un punto di vista
sintattico
, un formalismo molto diffuso per esprimere questa relazione fra oggetto e metodo e chiamato
dot notation
, dal nome
inglese
dot
del
punto
. Per esempio,
cdplayer.play()
rappresenta l'invocazione del metodo
play
sull'oggetto
cdplayer
.
Il riferimento a un oggetto nell'invocazione di un metodo serve anche a indicare il contesto operativo dell'attivazione del metodo; questo infatti ha la possibilita di accedere a tutti i dati interni dell'oggetto su cui e stato invocato. All'atto della chiamata o invocazione vanno passati, se richiesti dal metodo, i valori dei parametri da passare (
parametri attuali
).
La categoria di metodi piu comune e quella dei metodi che, come si e detto sopra, vengono invocati con riferimento a un oggetto; questi possono essere detti anche
metodi di istanza
. I
metodi di classe
- detti anche
metodi statici
- rappresentano invece operazioni che non sono da riferirsi ai singoli oggetti, ma alla classe nel suo insieme. Per richiamare o invocare un metodo statico basta scrivere il nome del metodo seguito dalla specifica dei
parametri attuali
.
Esempio generico in Java:
public static
tipo_ritorno <nome_Metodo> (tipo_parametro1 param1, ... , tipo_parametroN paramN){
...
blocco_istruzioni
;
...
return
<oggetto_tipo_metodo>;
}
Una particolare categoria di metodi e costituita dai
costruttori
,
[N 2]
che vengono invocati implicitamente ogni volta che un oggetto viene creato, e che hanno lo scopo generale di inizializzarne i dati interni. In molti linguaggi, tra cui ad esempio
Java
,
C++
,
C#
e
PHP
(fino alla versione 4), i
costruttori
sono facilmente distinguibili perche il loro nome deve coincidere con quello della classe di appartenenza.
Esempio generico in Java:
'''
public
'''
<
nome_classe
>
(
tipo_parametro1
param1
,
...,
tipo_parametroN
paramN
)
{
attributo1
=
param1
;
...
attributoN
=
paramN
;
}
In programmazione a oggetti, le
classi astratte
sono classi che rappresentano concetti troppo generali (e quindi astratti) per poter avere istanze dirette. In una classe di questo genere puo accadere che, analogamente, un metodo rappresenti un'operazione troppo astratta per poter avere un'implementazione. Un
metodo astratto
e un metodo privo di
implementazione
(definito in una classe astratta) che rappresenta un'operazione generale.
Un esempio potrebbe essere un ipotetico metodo
area()
nella classe
Poligono
. Sebbene si possa dire che di ogni poligono si puo calcolare l'area, potrebbe non essere semplice scrivere le istruzioni che svolgono effettivamente tale calcolo in termini cosi generali. Tale calcolo si puo invece agevolmente introdurre nelle implementazioni di specifiche sottoclassi di
Poligono
, come
Rettangolo
. Dichiarando il metodo
area
nella classe
Poligono
come metodo astratto, si indica che tutti i poligoni (tutte le sottoclassi di
Poligono
) devono avere quell'operazione, e allo stesso tempo
non
la si fornisce (implementata) nel corpo della classe. La conseguenza e che ogni sottoclasse dovra necessariamente fornire una propria implementazione del metodo attraverso
overriding
.
[N 3]
Un
metodo di accesso
(
accessor method
in
inglese
) e un tipo di metodo, di solito molto semplice e composto da poche righe di codice, che consente l'accesso (in lettura o scrittura) a un
attributo
dell'oggetto. L'uso di metodi di accesso e preferibile rispetto all'accesso diretto ai dati di stato in quanto compatibile con il principio dell'
information hiding
. La pratica di scrivere metodi di lettura e di scrittura degli attributi e talmente diffusa che in letteratura esistono nomi specifici per questo genere di metodi: setter (per un metodo che scrive un attributo) e getter (per un metodo che serve a leggere il valore di un attributo). Molti
IDE
(per esempio
Netbeans
e
Eclipse
) forniscono strumenti di
refactoring
che consentono la generazione automatica dei
getter
e dei
setter
degli attributi degli oggetti.
Un
metodo di estensione
(
extension method
in
inglese
) e un tipo di metodo che, una volta dichiarato, viene aggiunto automaticamente ad una
classe
o ad un tipo dopo la sua
compilazione
. Non c'e differenza sintattica tra la chiamata ad un metodo di estensione e la chiamata ad un metodo dichiarato nella definizione del
tipo
.
[1]
I metodi di estensione esistono in molti
linguaggi di programmazione
; in
C#
, ad esempio, vengono
implementati
come metodi
statici
all'interno di classi statiche, e il primo argomento della loro firma ha per tipo la classe estesa ed e preceduto dalla
parola chiave
"
this
". Il vantaggio dei metodi di estensione e la possibilita di evitare la creazione di vari helper, solitamente sotto forma di classi statiche con metodi statici, che rappresenterebbero un'alternativa peggiore dal punto di vista della leggibilita del
codice
. Inoltre, i metodi di estensione vengono automaticamente integrati nell'
Intellisense
dell'
ambiente di sviluppo
Visual Studio
, migliorando cosi anche la manutenzione del codice stesso. Il motivo principale per cui i metodi di estensione furono introdotti e rappresentato da
LINQ
, componente del
.NET Framework
di
Microsoft
dal 2007.
Esempio in C# di una classe con due metodi d'estensione della classe
String
: il primo ne capovolge il contenuto, e il secondo ne trasforma in maiuscola la prima lettera:
public
static
class
StringExtensions
{
public
static
string
Reverse
(
this
string
input
)
{
if
(
string
.
IsNullOrEmpty
(
input
))
{
return
string
.
Empty
;
}
char
[]
chars
=
input
.
ToCharArray
();
Array
.
Reverse
(
chars
);
return
new
String
(
chars
);
}
public
static
string
FirstCharToUpper
(
this
string
input
)
{
if
(
string
.
IsNullOrEmpty
(
input
))
{
return
string
.
Empty
;
}
return
char
.
ToUpper
(
input
[
0
])
+
input
.
Substring
(
1
);
}
}
- Annotazioni
- ^
La metafora della chiamata di metodo come
messaggio
deriva storicamente dalla terminologia di
Smalltalk
, uno dei primi
linguaggi di programmazione
a oggetti, ed e tuttora molto diffusa (in certi contesti, per esempio, viene utilizzata anche nella terminologia del
linguaggio di modellazione
UML
).
- ^
Nella terminologia tecnica dei vari linguaggi i
costruttori
vengono talvolta classificati come metodi, altre volte no.
- ^
Piu propriamente, una sottoclasse
potrebbe
non fornire l'implementazione di
area
, ma in tal caso il metodo rimarrebbe astratto anche nella sottoclasse. Poiche i metodi astratti sono ammessi solo nelle classi astratte, la sottoclasse dovrebbe quindi a sua volta essere astratta. Questo schema puo essere effettivamente usato per rappresentare gerarchie di concetti astratti.
- Fonti