Non ci sono funzioni di per sé in Java. Tutto quello che hai sono i metodi. Per imitare le funzioni, Java generalmente utilizza metodi statici (come in java.lang.Math
).
Esistono numerosi linguaggi orientati agli oggetti che forniscono funzioni indipendenti, tra cui Python, Ruby, JavaScript, C ++, Object Pascal e anche (yuck) PHP. C'è una buona ragione dietro a questo.
Un metodo è fondamentalmente una funzione con un parametro aggiuntivo (invisibile in Java). Si fa riferimento ad esso come this
. Quella cosa this
ti consente di accedere all'oggetto il cui metodo viene chiamato, così puoi pensare che l'intero oggetto sia sempre un parametro implicito per un metodo, in aggiunta ai parametri che normalmente definisci.
Un metodo ha senso se fa uso del suo oggetto: chiama altri metodi e / o accede ai membri dei dati. Ad esempio, un elenco può avere un metodo getLength()
che sa come calcolare la lunghezza dell'elenco, ad es. esaminando ciascun membro. Ovviamente utilizza l'oggetto implicito this
, ovvero l'elenco. Questo è il motivo per cui non ha bisogno di parametri espliciti.
Altrimenti, una funzione è sufficiente. Ad esempio, per calcolare un coseno di un angolo hai solo bisogno dell'angolo e nessun altro stato, quindi cos(float angle)
potrebbe essere una funzione, e dipende solo dal parametro angle
esplicito.
Un'altra cosa importante è il metodo che sovrascrive . (Per il mio ming, questa è una pratica discutibile, ma Java lo usa molto ampiamente.) Dichiari una certa classe (chiamala Z
) una sottoclasse di un'altra classe (chiamala A
) e modifica l'implementazione di alcuni dei suoi metodi (supponiamo di eseguire il metodo overrode foo()
).
La sottoclasse funziona come la classe base (si dice che fornisca la stessa interfaccia ) ma lo fa con diversi mezzi. In base al principio di sostituzione di Liskov , puoi dichiarare una variabile di tipo A
, assegnargli un'istanza di tipo Z
e invoca il metodo foo()
; ciò che verrà invocato è l'implementazione di Z
di foo()
, non A
's. Cioè, il metodo da chiamare verrà cercato in fase di runtime, in base al tipo effettivo dell'oggetto. Questo è noto come "metodo di invio dinamico" o "metodi virtuali".
Il metodo che sovrascrive fornisce automaticamente non è facile da emulare direttamente con le funzioni. (Con le funzioni, le cose simili vengono solitamente eseguite con "callback" o "funzioni di ordine superiore").
In alcune lingue, come Java e C #, puoi definire "metodi statici" che non ricevono un parametro this
. Funzionano esattamente come funzioni "standalone" e usano la classe come spazio dei nomi. Talvolta il namespace può avere senso quando viene usato un metodo statico di una classe per cercare o creare nuove istanze di quella classe.
Spero che ora abbia un quadro migliore.