Overloading

Oggi discuteremo di un altro importante costrutto specifico del paradigma della programmazione orientata agli oggetti: vedremo insieme cosa si intende per overloading (in italiano: sovraccarico) e come questa tecnica sia implementata in FreeBASIC.

Introduzione

Abbiamo visto nell’articolo introduttivo alla programmazione orientata agli oggetti in FreeBASIC che tra i membri di una classe, oltre alle proprietà ci sono anche i cosiddetti metodi che, in ultima analisi, non sono altro che procedure: ovvero subroutines o funzioni.

Come ben sappiamo ogni procedura è caratterizzata da uno specifico nome, dalla possibilità di ricevere degli argomenti e, nel caso delle funzioni, anche di restituire un valore di ritorno.

La lista degli argomenti viene definita la firma (signature) della procedura.

La tecnica di overloading consiste nello scrivere più procedure aventi lo stesso nome, ma firma differente.

Questa tecnica viene normalmente applicata anche alla procedura costruttore.

Utilità della tecnica di overloading

Arrivati a questo punto è lecito domandarci: ma a che ci serve applicare questa tecnica?

La risposta è semplice:

  • Se sovraccarichiamo un costruttore abbiamo la possibilità di creare degli oggetti (istanze della nostra classe) inizializzandoli in maniera differente.
  • Se sovraccarichiamo un metodo abbiamo la possibilità di specializzare un certo comportamento in base proprio ai parametri passati come argomenti.

Esempio di overloading su un metodo

''definizione della classe "sommatore"
type sommatore
  public:
    ''dichiarazione del metodo "somma" sovraccaricato
    declare function somma(a as integer, b as integer) as integer
    declare function somma(a as string, b as string) as string
  ''dimensionamento della proprietà "etichetta"
  dim as string etichetta = "Il risultato e': "
end type

''definizione delle funzioni "somma"
function sommatore.somma(a as integer, b as integer) as integer
  return a+b
end function
function sommatore.somma(a as string, b as string) as string
  return a+b
end function

''creazione dell'oggetto istanza della classe "sommatore"
dim as sommatore mio_sommatore

''primo caso: somma con valori interi
dim as integer c, d
c = 3
d = 4
print mio_sommatore.etichetta & mio_sommatore.somma(c,d)

''secondo caso: somma con valori stringa
dim as string e, f
e = "3"
f = "4"
print mio_sommatore.etichetta & mio_sommatore.somma(e,f)

sleep ''pausa

Nota: se applichiamo la tecnica di overloading alle procedure che sono dei membri di una classe, non è necessario specificarlo esplicitamente, ma se vogliamo applicarla alle normali procedure, allora è obbligatorio far seguire al nome della procedura la parola-chiave overload, almeno per la prima procedura che si vuole sovraccaricare.

Bene. Un altro piccolo passo è stato fatto. 🙂

Nel prossimo articolo parleremo del concetto di polimorfismo.

FreeBASIC -passaggio di argomenti

Nel precedente articolo abbiamo introdotto il concetto di procedura, sia nella forma di subroutine che di funzione.

In questo nuovo articolo vedremo un aspetto fondamentale che riguarda le procedure: ovvero il passaggio di argomenti:

Quando si chiama una procedura è possibile passarle alcune informazioni attraverso degli argomenti (ovvero variabili od oggetti). All’interno della procedura ci si riferirà a queste informazioni chiamandole parametri.

Per fare in modo che una procedura possa gestire degli argomenti, è necessario che nella sua dichiarazione venga specificata la lista dei parametri. Ciascun elemento di questa lista viene descritto attraverso un nome e la relativa tipologia di dato:

'dichiarazione di una subroutine con lista dei parametri
declare sub scheda (n as string, c as string, e as integer)

'chiamata della subroutine con argomenti racchiusi
'tra parentesi
scheda ("Mario", "Rossi", 182)

'definizione della subroutine
sub scheda (n as string, c as string, e as integer)
  print "nome: "; n
  print "cognome: "; c
  print "età: "; e
end sub

Sebbene in FreeBASIC, quando si chiama una procedura, non è obbligatorio racchiudere gli argomenti tra parentesi, per una migliore leggibilità del codice, soprattutto in presenza di più argomenti, è preferibile utilizzarle.

Sino a questo momento abbiamo parlato genericamente di passaggio di informazioni. Occorre però sapere che in FreeBASIC è possibile passare queste informazioni in due diverse modalità:

  1. passaggio per valore (che in assenza di specifica differente dichiarazione è la modalità di default)
  2. passaggio per riferimento

Vediamo ora di capire bene la differenza tra questi due diversi modi di passare le informazioni.

Passaggio di argomenti per valore (byval)

Abbiamo detto che questa è la modalità di default utilizzata in FreeBASIC.

In pratica quando si passa un argomento per valore, il relativo parametro all’interno della procedura riceve in realtà una copia del valore dell’argomento, e quindi qualsiasi variazione del valore del parametro che potrà avvenire all’interno della procedura non si ripercuoterà sul valore originale dell’argomento.

Ciò significa, per esempio, che se l’argomento è una variabile, il valore di questa variabile rimane inalterato.

Passaggio di argomenti per riferimento (byref)

Se si ha la necessità di fare in modo che le operazioni all’interno di una procedura su un determinato parametro abbiano effetto direttamente sulla variabile, o sull’oggetto passato come argomento in fase di chiamata della procedura, allora è necessario passare questo argomento anteponendo la parola-chiave byref:

'dichiarazione di una variabile
dim a as integer

'dichiarazione della subroutine
declare sub raddoppia (byref n as integer)

'valorizzazione iniziale della variabile
a = 5

'stampa
print "il valore di a prima della chiamata è: "; a

'chiamata della subroutine senza utilizzare le parentesi
raddoppia a

'stampa
print "il valore di a dopo la chiamata è: "; a

'definizione della subroutine
sub raddoppia (byref n as integer)
  n *= 2
end sub

Bene. Per oggi ci fermiamo qui. 🙂

Nel prossimo articolo approfondiremo l’argomento relativo al ritorno dei valori dopo la chiamata di una funzione.

FreeBASIC – procedure

Dopo aver introdotto nel precedente articolo il tipo di dato definito da noi, in questo nuovo articolo faremo la conoscenza delle procedure.

Iniziamo dandone una sintetica definizione:

Una procedura è un blocco di codice che può essere eseguito tramite una chiamata da qualsiasi punto del nostro programma per un numero indefinito di volte.

La stessa definizione ci aiuta a capire che ha senso scrivere una procedura ogni qual volta ci accorgiamo che una specifica sequenza di istruzioni deve essere utilizzata più volte durante la scrittura del nostro programma.

Scrivere infatti una sola volta un blocco di codice, oltre a farci risparmiare tempo, ci evita di dover andare a ripetere lo stesso tipo di correzione, su diversi punti del programma, ogni qual volta ci dovessimo accorgere che una modifica si rende necessaria. Questo aumenta la cosiddetta manutenibilità del codice.

Tipi di procedure

In FreeBASIC ci sono due diversi tipi di procedure:

  1. procedure che non restituiscono alcun valore. In questo caso le si definiscono con il termine inglese subroutines;
  2. procedure che restituiscono un valore. In questo caso le si definiscono più propriamente funzioni.

Subroutine

Per lavorare con una subroutine occorre prima dichiararla con la parola-chiave declare e poi definirla con con la parola-chiave sub.

La dichiarazione assegna un nome (o etichetta) alla procedura, mentre la definizione contiene le vere e proprie istruzioni che dovranno essere eseguite ogni volta che verrà fatta una chiamata con il nome della procedura:

'dichiarazione della procedura
declare sub mia_procedura

'chiamata della procedura
mia_procedura

'definizione della procedura
sub mia_procedura
  print "ciao"
end sub

Come è possibile notare, per poter chiamare una procedura occorre che la chiamata sia successiva alla sua dichiarazione, mentre il corpo della procedura vera e propria può essere scritto sotto alla chiamata o, come più spesso accade, in un file separato.

Funzione

Come abbiamo già detto, una funzione differisce da una semplice procedura per il fatto che la funzione restituisce sempre un valore nel punto esatto dove questa viene chiamata.

Anche una funzione, come avviene per una subroutine, va prima dichiarata assegnandole un nome. Soltanto successivamente va definita attraverso la parola-chiave function. Per la funzione è anche necessario dichiarare il tipo di dato restituito e questo lo si fa all’atto della dichiarazione:

'dichiarazione della funzione
declare function mia_funzione as integer

'dichiarazione di una variabile
dim i as integer

'chiamata della funzione
i = mia_funzione
print i

'definizione della funzione
function mia_funzione as integer
  return 10
end function

Bene. Ora che sappiamo usare anche le procedure possiamo cominciare a scrivere i nostri primi veri programmi procedurali. 😉

A rileggerci al prossimo articolo dove approfondiremo la conoscenza delle procedure affrontando il tema del passaggio di argomenti.