domenica 28 settembre 2014

Ereditarietà

Il concetto di Ereditarietà Informatica

In informatica l'ereditarietà è uno dei concetti fondamentali, essa costituisce infatti il secondo principio fondamentale della programmazione ad oggetti.

In generale si può definire come un meccanismo che consente di creare nuove classi che siano basate su altre già definite in precedenza; a seconda del linguaggio di programmazione, l'ereditarietà può essere ereditarietà singola o semplice (ogni classe può avere al più una superclasse diretta) o multipla (ogni classe può avere più superclassi dirette).



Concetto di ereditarietà nel mondo reale:

È semplice poter osservare esempi di ereditarietà nel mondo reale. Ad esempio, esistono al mondo centinaia di tipologie diverse di mammiferi: cani, gatti, uomini, balene e così via. Ognuna di tali tipologie di mammiferi possiede alcune caratteristiche che sono strettamente proprie (ad esempio, soltanto l’uomo è in grado di parlare) mentre esistono, d’altra parte, determinate caratteristiche che sono comuni a tutti i mammiferi (ad esempio, tutti i mammiferi hanno il sangue caldo e nutrono i loro piccoli).
Nel mondo Object Oriented, potremmo riportare tale esempio definendo un oggetto Mammifero che inglobi tutte le caratteristiche comuni ad ogni mammifero. Da esso, poi, deriverebbero gli altri oggetti figlio: Cane, Gatto, Uomo, Balena, etc.
L’oggetto cane, per citarne uno, erediterà, quindi, tutte le caratteristiche dell’oggetto mammifero ma a sua volta conterrà delle caratteristiche aggiuntive, distintive di tutti i cani come ad esempio: ringhiare o abbaiare.
Il paradigma OOP, ha quindi carpito l’idea dell’ereditarietà dal mondo reale e lo stesso concetto viene applicato ai sistemi software che utilizzano tale tecnologia.
Come possiamo passare l’eredità da padre a figlio?
Abbiamo parlato di Classe Padre e Classe Figlio, l’ereditarietà consente alla classe Figlio di ereditare ogni membro della classe Padre, e poi aggiungere e modificare le cose secondo le nuove funzionalità da realizzare. Avendo la necessità di utilizzare tutti i membri di una classe padre senza doverli dichiarare di nuovo, ci basterà mettere una sola dichiarazione nell'header della classe figlio:

class pesce_rosso : public pesce
{
    ...
};

In tal caso, la classe derivata si chiama pesce_rosso. La classe base ha visibilità pubblica e si chiama pesce.

*!* Quando una classe eredita da un'altra, ne eredita tutti i membri. Questo porta a due problemi:
proteggere i membri di una classe in modo che i suoi potenziali figli non siano in grado di accederli.
far sì che una classe figlia impedisca l'accesso da parte del mondo esterno alla parte ereditata dalla sua classe padre.

Ereditarietà privata, protetta o pubblica:

Il meccanismo di ereditarietà, pur essendo abbastanza semplice, richiede una certa attenzione per non cadere in errori perchè dipende dallo standard della classe base.
Gli attibuti ed i membri che vengono ereditati dalla classe base possono cambiare la loro visibilità nella classe figlio, in base allo specificatore/modificatore d’accesso con il quale si esegue l’ereditarietà stessa, nel dettaglio:

Se lo specificatore d’accesso è public:
i public restano public
i protected restano protected
i private non possono essere trasferiti


Se lo specificatore d’accesso è private:
i public diventano private
i protected diventano private
i private non possono essere trasferiti


Se lo specificatore d’accesso è protected:
i public diventano protected
i protected restano protected
i private non possono essere trasferiti


Tabella riassuntiva:

*!* Durante l’ereditarietà un accesso può restringersi o restare uguale ma mai ampliarsi.

Esempio di codice:

#include <iostream>
using namespace std;
class persona{   //dichiarazione della classe persona
        public:   // con public rendo i metodi accessibili dal main()
        persona();   //costruttore senza passaggio di parametri
       ~persona();   //distruttore
        void visualizzaAnagrafica();   //metodo per visualizzare dati Anagrafica
        char nome[15];   //dichiarazione stringa nome
        char cognome[15];   //dichiarazione stringa cognome
        int eta;   //dichiarazione variabile eta
        };


persona::persona()   //definizione del costruttore senza passaggio di parametri
{
cout <<" Inserisci Nome: ";
cin >> nome;   //salvo l'input da utente nella stringa nome
cout << endl <<" Inserisci Cognome: ";
cin >> cognome;   //salvo l'input da utente nella stringa cognome
cout << endl <<" Inserisci eta': ";
cin >> eta;   //salvo l'input da utente nella variabile eta
cout << endl;
}

class personaEstipendio : public persona {   //creo Classe Figlio personaEstipendio da Classe Padre persona con metodo "public"
        public:
        personaEstipendio();   //costruttore personaestipendio senza passaggio di parametri
       ~personaEstipendio();   //distruttore
        void visualizzaLavorativa();   //metodo per visualizzare dati Lavorativi
        private:
        char tipoContratto[15];
        int importoStipendio;
        };

personaEstipendio::personaEstipendio()   //definizione del costruttore senza passaggio di parametri
{
cout <<" Inserisci il tipo di contratto lavorativo: ";
cin >> tipoContratto;   //salvo l'input da utente nella stringa tipoContratto
cout << endl <<" Inserisci importo stipendio: ";
cin >> importoStipendio;   //salvo l'input da utente nella variabile importoStipendio
}

void persona::visualizzaAnagrafica()   //definizione metodo visualizza della Classe Padre
{ cout << endl << " Dati dipendente: "<< nome <<" - " <<cognome <<" - " <<eta <<endl;   //visualizzo i dati inseriti dall'utente
}

void personaEstipendio::visualizzaLavorativa()   //definizione metodo visualizza della Classe Figlio
{ cout <<" Dati Contratto: tipo di Contratto "<< tipoContratto <<" Importo percepito " <<importoStipendio <<endl;   //visualizzo i dati inseriti dall'utente
}

persona :: ~persona()   //definizione del distruttore per comprendere funzionamento
{
   cout << "sono il distruttore Padre";
}

personaEstipendio :: ~personaEstipendio()   //definizione del distruttore per comprendere funzionamento
{
   cout << "sono il distruttore Figlio";
}

main()
 {
  char menu;
  do{
  cout << "PROVE DI EREDITARIETA':\nData una Classe Padre con dati anagrafici persona si crei una Classe Figlio \nche contenga anche dati lavorativi";
  cout << endl << endl;
  cout << "Inserimento da istanza oggetto Padre:";
  cout << endl << endl;
  persona anagrafica;   //istanzio l'oggetto anagrafica di classe Padre tramite costruttore senza passaggio di parametri
  cout << "Inserimento da istanza oggetto Figlio:";
  cout << endl << endl;
  personaEstipendio lavorativa;   //istanzio l'oggetto lavorativa di classe Figlio tramite costruttore senza passaggio di parametri
  cout << endl;
  cout << "Visualizzo oggetto PADRE:";
  cout << endl;
  anagrafica.visualizzaAnagrafica();   //chiamata al metodo visualizza dell'oggetto Padre anagrafica
  cout << endl;
  cout << "Visualizzo oggetto FIGLIO:";
  cout << endl;
  lavorativa.visualizzaAnagrafica();   //chiamata al metodo visualizzaAnagrafica dell'oggetto Figlio
  lavorativa.visualizzaLavorativa();   //chiamata al metodo visualizzaLavorativa dell'oggetto Figlio
  cout << endl;
        cout << "Vuoi ripetere il programma? ";
        cout << endl;
        cin >> menu;
  }while((menu=='s')||(menu=='S'));   //se l'utente non vuole ripetere il programma, fine
  cout << endl << endl << endl;
  return 0;
}

giovedì 25 settembre 2014

Compito lezione 24/09/2014 - Esercitazione sull'utilizzo dei Costruttori

Esercitazione sull'utilizzo dei Costruttori con e senza passaggio di parametri, degli ambienti public e private, dei metodi e degli attributi.

#include <iostream>
using namespace std;
class persona{   //dichiarazione della classe persona
        public:   // con public rendo i metodi accessibili dal main()
        persona();   //costruttore senza passaggio di parametri
        persona(int a);   //costruttore con passaggio di un parametro

       ~persona();   //distruttore
        void aggiorna();   //metodo aggiorna
        void visualizza();   //metodo visualizza
        private:   // con private rendo gli attributi non accessibili al di fuori della classe a cui appartengono
        char nome[15];   //dichiarazione stringa nome  
        char cognome[15];   //dichiarazione stringa cognome
        int eta;   //dichiarazione variabile eta
        };

persona::persona()   //definizione del costruttore senza passaggio di parametri
{
cout <<" Inserisci Nome: ";
cin >> nome;   //salvo l'input da utente nella stringa nome
cout << endl <<" Inserisci Cognome: ";
cin >> cognome;   //salvo l'input da utente nella stringa cognome
cout << endl <<" Inserisci eta': ";
cin >> eta;   //salvo l'input da utente nella variabile eta
}

persona::persona(int a)   //definizione del costruttore con passaggio di un parametro
{
cout << endl <<" Inserisci Nome: ";
cin >> nome;   //salvo l'input da utente nella stringa nome
cout << endl <<" Inserisci Cognome";
cin >> cognome;   //salvo l'input da utente nella stringa cognome
eta=a;   //passo il valore del parametro a ricevuto dalla chiamata nel main() alla variabile eta
cout << endl <<"L'eta' passata dal main e': " <<a<< endl;
}

void persona::visualizza()   //definizione metodo visualizza
{ cout << endl << " Dati dipendente: "<< nome <<" - " <<cognome <<" - " <<eta <<endl;   
//visualizzo i dati inseriti dall'utente
}

persona :: ~persona()   //definizione del distruttore per comprendere funzionamento
{
   cout << "sono il distruttore";
}

void persona :: aggiorna()   //definizione metodo aggiorna
{
   visualizza();   //chiamata al metodo visualizza
   char mod;   //variabile char di appoggio per scelta operazione utente
   do{
      cout << " Vuoi modificare i dati inseriti? S/N";   
//chiedo conferma all'utente per la modifica o meno dei dati inseriti
      cout << endl;
      cin >> mod;  
      if ((mod=='S')||(mod=='s'))   //se l'utente vuole modificare i dati
          persona();   //richiamo il costruttore
      else if ((mod!='N')&&(mod!='n'))   
//altrimenti controllo se la risposta fornita dall'utente è diversa da n o N
         {
          cout << " Dato non corretto";   
//in tal caso non avendo risposto ne con s-S ne con n-N vuol dire che ha dato una risposta non corretta e glielo comunico
         }
      }while(((mod=='S')||(mod=='s'))||((mod!='n')&&(mod!='N')));   
//continuo la procedura mente la risposta è diversa da n-N

}
 main()
 {
  char menu;
  do{
  cout << "Compito su lezione 24/09/2014";
  cout << endl << endl;
  cout << "Inserimento da istanza oggetto dipendente con Costruttore senza passaggio \ndi parametri:";
  cout << endl << endl;
  persona dipendente;   
//istanzio l'oggetto dipendente di classe persona tramite costruttore senza passaggio di parametri
  cout << "Inserimento da istanza oggetto dipendente con Costruttore con passaggio \ndi parametri:";
  cout << endl;
  persona dipendenteInt(5);   
//istanzio l'oggetto dipendente di classe persona tramite costruttore con passaggio di un parametro
  cout << "Richiamo a metodo 'Aggiorna()' con al suo interno richiamo al metodo 'Visualizza'";
  cout << endl << endl;
  dipendente.aggiorna();   //chiamata al metodo aggiorna dell'oggetto dipendente
  cout << "Inserimento da vettore di oggetti dipendente con Costruttore senza passaggio (3 elementi) \ndi parametri:";
  cout << endl << endl;
  persona dipv[3];   
//istanzio un vettore di oggetti dipendente di classe persona con tre elementi tramite costruttore senza passaggio di parametri
        cout << "Vuoi ripetere il programma? ";
        cout << endl;
        cin >> menu;
  }while((menu=='s')||(menu=='S'));   //se l'utente non vuole ripetere il programma, fine
  cout << endl << endl << endl;
  return 0;
}



mercoledì 24 settembre 2014

Costruttori in c++

I Costruttori - Lezione 3 OOP 


Il costruttore è eseguito ogni volta che viene creato un nuovo oggetto della classe cui appartiene.
Tramite il costruttore possiamo determinare il comportamento che l’oggetto avrà alla sua creazione: ad esempio possiamo utilizzare i costruttori per inizializzare le variabili della classe.

Come si dichiara il costruttore di una classe?

Il costruttore di una classe deve sempre avere lo stesso nome della classe in cui è definito e può accettare argomenti;
Prova::Prova(int x, int y)   //dichiarazione di un costruttore con passaggio di due parametri interi

*!* Se non dichiarato esplicitamente all'interno della classe, il costruttore viene generato automaticamente dal compilatore (costruttore di default).

*!* Non bisogna specificare il tipo di ritorno (neanche void), un costruttore ritorna "qualcosa" e precisamente l'oggetto che ha appena creato.

Possono esistere più costruttori in una stessa classe. Il C++ li distingue in base alla lista degli argomenti.
Se invece in una classe esiste almeno un costruttore con argomenti, il C++ non mette a disposizione alcun costruttore di default e perciò questo, se necessario, va esplicitamente definito come metodo della classe. In sua assenza, i costruttori con argomenti non vengono invocati automaticamente e pertanto ogni istruzione del programma che determini, direttamente o indirettamente, la creazione di un oggetto, deve contenere la chiamata esplicita di uno dei costruttori disponibili, nel modo che dipende dalla categoria dell'oggetto interessato. 

Esempio di codice con Costruttori definiti dal programmatore:



sabato 20 settembre 2014

Programmazione ad Oggetti OOP Lezione 2

Utilizzo delle Classi: Seconda Lezione OOP 18-19/09/2014

Esempio:
Class A
   {
      int a;
      char b[15];
      f();
   };

int main()
{
    A Object;               
*!* Un oggetto per essere creato va dichiarato( Classe+ Nome Oggetto), qui vediamo la dichiarazione di un Oggetto di nome "Object" di Classe"A".
}


I programmi sono composti da parti visibili e/o invisibili: le parti visibili possono essere utilizzate all'interno del main(), le parti invisibili al contrario no.
Per rendere una Classe visibile devo scrivere il comando "public:"

*!* Le Classi possono essere Pubbliche, Private e Protette, l'insieme di tutto quello che è pubblico costituisce l'interfaccia. Non c'è un ordine con il quale porre una tipologia (pub/priv/prot) prima dell'altra l'importante è che questa appaia una volta sola.

*!* Le parti Private sono visibili sempre all'interno della Classe

*!* In C++ se non viene dichiarato diversamente la Classe è considerata Privata di default, in JAVA invece viene considerata Pubblica di default.

Vediamo ora degli esempi risultanti da IDE C++:
con Classe A public:



con Classe A private (avremo nel nostro caso una comunicazione di errore da parte del compilatore:



Anno scolastico 2014/2015 Programmazione ad Oggetti OOP Lezione 1

Programmazione ad oggetti: (OOP, Object Oriented Programming) 17/09/2014


Il concetto che sta alla base della programmazione ad oggetti è quello della classe. La classe è infatti il progetto dell'oggetto. 

Le classi definiscono dei tipi di dato e permettono la creazione degli oggetti secondo le caratteristiche definite nella classe stessa; il concetto alla base della classe è quello delle strutture visto l'anno scorso, la differenza che distingue una classe da una struttura è che all'interno della classe possono essere presenti anche delle funzioni. 

In particolare le variabili della classe vengono denominate proprietà o attributi, le funzioni invece metodi.

Da una classe può essere creato un oggetto (tecnicamente un oggetto è un istanza di una classe) il quale conterrà tutti gli attributi e i metodi definiti dalla classe.

*!* La Classe è il progetto di un Oggetto, un esempio di classe in C è la dichiarazione di variabile int

Lavorativamente parlando possiamo distingue due tipi di programmatori nell'ambito della OOP:
1 Programmatore che progetta l'oggetto (ricordiamo che 1 progetto = più oggetti)
1 Programmatore che utilizza l'oggetto tramite sua relativa interfaccia
da questo ne consegue che la prima cosa da imparare è come si utilizza l'interfaccia dell'oggetto di cui abbiamo bisogno.

Per fare un programma utilizzando la OOP abbiamo bisogno di un IDE (Integrated development environment) orientato ad oggetti, tra i più diffusi figurano:
JAVA
C#
C++
...
*!* Questi IDE non sono totalmente OOP in quanto non prevedono l'utilizzo di soli oggetti, in questo ambito solo il progetto Eiffel si può definire come totalmente orientato agli oggetti

*!* Framework: contenitore di oggetti creati per risolvere questioni specifiche.

Come si crea un oggetto?

Un oggetto a livello concettuale si dichiara come una variabile, nel dettaglio la Classe rappresenta il tipo dell'Oggetto.
Vediamo un esempio:
Supponiamo di voler creare una Classe Persona con all'interno due attributi nome, stipendio e una funzione f:

Class Persona
   {
       char nome[15];
       int stipendio;
       f();
   }Dipendente;

notiamo che è del tutto simile a una dichiarazione di una struttura (a parte per la presenza di una funzione al suo interno). Nel nostro esempio la Classe Persona è il progetto e la variabile Dipendente è l'oggetto; così facendo abbiamo creato una Classe Persona con due campi e istanziato l'oggetto Dipendente.

*!* Per accedere ai campi di un oggetto si utilizza (come per le strutture) la notazione puntata: Dipendente.nome

lunedì 27 gennaio 2014

Calcolo combinatorio

# include <stdio.h>

int vett[4]={1,2,3,4};
int i,j,h,x;
void stampa(int v[],int dim);

int main()
{
 for(h=0;h<4;h++)
{
for(i=0;i<3;i++)
{
for(j=0;j<2;j++)
{
x=vett[2];   //inserisco valore vett[2] in variabile di appoggio
vett[2]=vett[3];   //inserisco valore vett[3] in vett[2]
vett[3]=x;   //inserisco valore salvato in x in vett[3]
stampa(vett,4);   //chiamata alla procedura di stampa con passaggio parametri vettore e dimensione per visualizzare vettore con combinazioni modificate in ciclo FOR
}
x=vett[2];   //rieseguo nuovamente l'operazione di scambio del ciclo FOR j per riposizionare il vettore alla situazione di scambio
vett[2]=vett[3];
vett[3]=x;

x=vett[1];   //inserisco valore vett[1] in variabile di appoggio
vett[1]=vett[2];   //inserisco valore vett[1] in vett[2]
vett[2]=x;   //inserisco valore salvato in x in vett[2]
}
x=vett[2];   //rieseguo nuovamente l'operazione di scambio del ciclo FOR j per riposizionare il vettore alla situazione di scambio
vett[2]=vett[3];
vett[3]=x;

x=vett[1];   //rieseguo nuovamente l'operazione di scambio del ciclo FOR i per riposizionare il vettore alla situazione di scambio
vett[1]=vett[2];
vett[2]=x;

x=vett[0];   //inserisco valore vett[1] in variabile di appoggio
vett[0]=vett[1];   //inserisco valore vett[1] in vett[2]
vett[1]=x;   //inserisco valore salvato in x in vett[2]
}
}

void stampa(int v[],int dim)   //procedura di stampa con passaggio parametri vettore e dimensione (4)
{
int y;   //dichiaro indice per ciclo FOR
for(y=0;y<dim;y++)   //eseguo ciclo FOR per visualizzare contenuto vettore
{
printf("%d\t",v[y]);   //stampa + TAB per posizioni vettore 
}
printf("\n\n");   //spaziatura a capo
}

Passaggio matrice nei parametri funzione carica e procedura stampa

# include <stdio.h>   //libreria

int matrice[3][3];   //dichiarazione matrice a due dimensioni 3x3
int i,j;   //indici per utilizzo matrice
int carica(int mat[][3], int dim);   //prototipo funzione carica con passaggio parametri matrice(con dimensione colonne) e dim per cicli FOR
void stampa(int mat[][3], int dim);   //prototipo procedura stampa con passaggio parametri matrice(con dimensione colonne) e dim per cicli FOR


int main()
{
    printf("\tMatrice con passaggio di parametri e grafica tabella\n");
    carica(matrice,3);   //chiamata alla funzione carica con passaggio parametri matrice e 3 per dim
    stampa(matrice,3);   //chiamata allaprocedura stampa con passaggio parametri matrice e 3 per dim
}

int carica(int mat[][3], int dim)   //definizione funzione carica con passaggio parametri matrice (con dimensione colonne) e dim per cicli FOR
{
for(i=0;i<dim;i++)
              for(j=0;j<dim;j++)
                   {
                   printf("\nInserisci il valore della riga %d e colonna %d:  ",i,j);
                   scanf("%d",&matrice[i][j]);
                   }
}

void stampa(int mat[][3], int dim)   //definizione procedura stampa con passaggio parametri matrice (con dimensione colonne) e dim per cicli FOR
{
        printf("\n\n|------|------|------|");
for(i=0;i<3;i++)
         {
          printf("\n\n|");             
       

              for(j=0;j<3;j++)
                   printf("  %d   |",matrice[i][j]);
                   printf("\n\n|------|------|------| ");
         }
}