Incapsulamento

Nella programmazione orientata agli oggetti, uno dei concetti fondamentali è quello dell’incapsulamento.

Quando definiamo una nostra classe, è bene restringere l’ambito di visibilità delle proprietà e dei metodi ai soli metodi che definiremo pubblici che fungeranno quindi da interfaccia verso il mondo esterno.

Con questa strategia di programmazione abbiamo i seguenti due vantaggi:

  • Possiamo modificare liberamente la logica dei metodi incapsulati senza che queste modifiche alterino il modo con cui altri oggetti si interfacciano con l’oggetto del tipo della nostra classe.
  • Impediamo l’accesso diretto alle proprietà in modo tale possiamo sviluppare del codice di controllo per impedire input non corretti.

Definizione dei diritti di accesso ai membri

In FreeBASIC abbiamo tre diverse tipologie per definire i diritti di accesso (ambito di visibilità) ai membri di una classe (proprietà e metodi):

  1. public: in mancanza di una definizione esplicita da parte del programmatore, public è la classificazione di default. Questa classificazione permette il libero accesso al membro così definito non soltanto da parte di tutti gli altri membri della classe, ma anche dal codice e dalle procedure definite a livello dello stesso modulo: ovvero dello stesso file sorgente.
  2. protected: questa classificazione restringe l’accesso ad un determinato membro di una classe sia ai membri della stessa classe che a quelli di eventuali classi derivate.
  3. private: questa classificazione permette l’accesso ad un membro di una classe solo ed esclusivamente ai soli membri della classe.

Questa tre tipologie di classificazione hanno lo stesso effetto anche per le procedure costruttore e distruttore.

Buone pratiche di programmazione

Quando adottiamo il paradigma della programmazione orientata agli oggetti, in relazione al tema dei diritti di accesso ai membri di una classe sono state consolidate nel tempo delle cosiddette buone pratiche di programmazione che pervedono di adottare queste modalità di definizione del codice:

  • proprietà: è bene classificarle come private.
  • metodi per la logica di funzionamento interna dell’oggetto: è bene classificarli come protected.
  • metodi interfaccia: vengono classificati come public.

Esempio

''definizione della classe strumento_musicale
type strumento_musicale
  public:
    declare sub imposta_strumento(s as string)
    declare function ottieni_strumento() as string
  protected:
    declare function controllo_tipo(s as string) as string
  private:
    dim as string strumento
end type

''implementazione dei metodi della classe strumento_musicale
sub strumento_musicale.imposta_strumento(s as string)
  if controllo_tipo(s) = "OK" then
    this.strumento = s
  else
    this.strumento = "non previsto nella nostra scuola."
  end if
end sub

function strumento_musicale.ottieni_strumento() as string
  return this.strumento
end function

function strumento_musicale.controllo_tipo(s as string) as string
  if s = "chitarra" then
    return "OK"
  else
    return ""
  end if
end function

''crea un oggetto del tipo strumento_musicale
dim as strumento_musicale mio_strumento_musicale
dim as string mio_strumento
input "Qual e' il tuo strumento"; mio_strumento 
mio_strumento_musicale.imposta_strumento(mio_strumento)
print "Lo strumento che hai inserito e': " & _
mio_strumento_musicale.ottieni_strumento()

''una eventuale chiamata diretta al metodo dichiarato
''protected genererebbe, in fase di compilazione, un
''errore di "accesso illegale ad un membro"
''mio_strumento_musicale.controllo_tipo(mio_strumento)

Bene! Abbiamo fatto insieme un altro piccolo passo nel mondo della programmazione ad oggetti.

Nel prossimo articolo vedremo come in FreeBASIC si applicano le tecniche di associazione ed ereditarietà. 🙂

FreeBASIC – variabile

Nel precedente articolo abbiamo discusso del concetto informatico di costante e di come utilizzarla nel nostro codice.

È arrivato quindi il momento di parlare della variabile cominciando a darne una sintetica definizione:

Una variabile è una etichetta che rimanda a dei dati registrati in una qualsiasi porzione di memoria che possono essere modificati in qualsiasi momento.

Dichiarazione

La prima cosa da fare quando vogliamo utilizzare una variabile nel nostro codice è dichiararla attraverso l’istruzione dim:

dim mia_variabile as string

Occorre però fare attenzione che i nomi delle nostre variabili rispettino due semplici regole sintattiche:

  1. i nomi possono contenere soltanto lettere maiuscole o minuscole, numeri e il carattere _ (trattino basso, underscore);
  2. i nomi non devono contenere degli spazi.

Come abbiamo già avuto modo di vedere nell’articolo dedicato specificatamente alla dichiarazione, questa assegna uno specifico tipo alla nostra variabile; ciò comporta che dovremo utilizzarla in maniera coerente nel nostro codice: ovvero se abbiamo dichiarato che la variabile è di tipo testo (string), non potremo utilizzarla direttamente in una espressione aritmetica, a meno che non operiamo intenzionalmente una sua conversione.

Ambito di utilizzo

A seconda del punto dove dichiariamo una variabile nel codice che stiamo scrivendo, questa avrà un suo specifico ambito di utilizzo (in inglese scope) che potrà essere:

  • limitato ad una procedura (subroutine o funzione);
  • limitato ad un modulo;
  • oppure utilizzabile ovunque all’interno dei moduli che compongono il nostro programma utilizzando la parola-chiave shared.

Bene, arrivati a questo punto siamo pronti per fare la conoscenza nel prossimo articolo di un tipo di variabile molto speciale: il vettore/matrice (più comunemente noto con il termine inglese array).