Incapsulamento ed estensibilità dei Tipi

OOP è un approccio equilibrato alla scrittura di software. I dati e il comportamento sono impacchettati insieme. L'incapsulamento crea tipi di dati definiti dall'utente, estendendo i tipi di dati del linguaggio ed interagendo con essi. L' estensibilità dei tipi è la possibilità di aggiungere al linguaggio tipi di dati definiti-dall'utente, che sono anche facili da utilizzare, così come i tipi di base.

Un tipo di dato astratto, per esempio, una stringa, è una descrizione dell' ideale, ben noto, comportamento del tipo.

L'utente che utlizza la stringa sa che le operazioni sulle stringhe, quali concatenazione o stampa, hanno un certo comportamento. Operazioni di concatenazione e stampa sono chiamate metodi.

Una certa implementazione di ADT può avere alcune limitazioni, per esempio, le stringhe possono essere limitate in lunghezza. Queste limitazioni influenzano il comportamento aperto a tutte. Al tempo stesso, dettagli di implementazione interni o privati ​​non influenzano direttamente il modo in cui l'utente vede l'oggetto. Ad esempio, la stringa è spesso implementata come un array, mentre l'indirizzo di base interno di questo array ed il suo nome non sono essenziali per l'utente.

L'incapsulamento è la capacità di nascondere i dettagli di implementazione quando vengono fornite le interfacce aperte per il tipo definito-dall'utente. In MQL5, così come in C++, definizioni di classe e struttura (class e struct) vengono utilizzate per le disposizioni di incapsulamento in combinazione con le parole chiave di accesso private, protected e public.

La parola chiave public indica che l'accesso ai membri che stanno dietro di esso, è aperto senza restrizioni. Senza questa parola chiave, i membri della classe sono bloccati per impostazione predefinita. I membri privati ​​sono accessibili solo da funzioni che sono membro soltanto della sua classe.

Funzioni di classe protette sono disponibili per funzioni di classe non solo nella sua classe, ma anche nelle sue classi eredi. Funzioni di classe pubbliche sono disponibili per qualsiasi funzione nell'ambito della dichiarazione di classe. La protezione permette di nascondere parte dell'implementazione della classe, impedendo cambiamenti inattesi nella struttura dei dati. Restrizioni all' accesso oppure oscuramento dei dati sono una caratteristica della programmazione orientata agli oggetti.

Di solito, le funzioni di classe sono protette e dichiarate con il modificatore protected, la lettura e la scrittura dei valori vengono eseguite utilizzando cosiddetti speciali metodi set-and-get che sono definiti dai modificatori pubblici di accesso.

 

Esempio:

class CPerson
  {
protected:
   string            m_name;                     // name
public:
   void              SetName(string n){m_name=n;}// imposta il nome
   string            GetName(){return (m_name);} // restituisce il nome
  };

 

Questo approccio offre diversi vantaggi. In primo luogo, dal nome della funzione possiamo capire ciò che fa - imposta o ottiene il valore di un membro della classe. In secondo luogo, forse in futuro ci sarà bisogno di cambiare il tipo della variabile m_name nella classe CPerson o in una delle sue classi derivate.

In questo caso, abbiamo bisogno solo di modificare l'implementazione delle funzioni SetName() e GetName(), mentre gli oggetti della classe CPerson saranno disponibili per l'utilizzo in un programma senza modifiche al codice, perché l'utente non sa nemmeno che il tipo di dati di m_name è cambiato.

Esempio:

struct Name
  {
   string            first_name;                 // nome
   string            last_name;                  // cognome
  };
 
class CPerson
  {
protected:
   Name              m_name;                     // nome
public:
   void              SetName(string n);
   string            GetName(){return(m_name.first_name+" "+m_name.last_name);}
private:
   string            GetFirstName(string full_name);
   string            GetLastName(string full_name);
  };
 
void CPerson::SetName(string n)
  {
   m_name.first_name=GetFirstName(n);
   m_name.last_name=GetLastName(n);
  }
 
string CPerson::GetFirstName(string full_name)
  {
   int pos=StringFind(full_name," ");
   if(pos>0) StringSetCharacter(full_name,pos,0);
   return(full_name);
  }
 
string CPerson::GetLastName(string full_name)
  {
   string ret_string;
   int pos=StringFind(full_name," ");
   if(pos>0) ret_string=StringSubstr(full_name,pos+1);
   else      ret_string=full_name;
   return(ret_string);
  }

Vedi anche

Tipi di Dati