Programmazione ad oggetti in C++ le sotto classi

Introduzione

Caso di studio in UML

La programmazione ad oggetti è basata su concetti fondamentali quali l’ereditarietà e il polimorfismo. La prima caratteristica è la possibilità di costruire una classe partendo da un’altra o più classi attraverso un’operazione di derivazione per costruire una sotto classe. Questa operazione risulta vantaggiosa per la possibilità di riutilizzo die metodi della classe da cui derivare la sotto classe e per specializzare e estendere in termini di attributi e funzionalità. Il termine polimorfismo indica la capacità di modificare il comportamento di metodi che hanno lo stesso nome ma operano in due classi differente. Questa operazione si chiama tecnicamente “override” dei metodi.

Caso di studio in UML

Nel diagramma UML sono definite due classi “Persona” e “Studente” la prima generica che rappresenta le carattertistiche anagrafiche di una persona e l’latra che rappresenta invece un’estensione della classe “Persona” per ottenere una classe derivata “Studente”.
Il diagramma UML è:


DIAGRAMMA uml CHE RAPPRESNETA la classe Peronsa che specializza la classe Studente.

Nel diagramma UML nella classe “Persona” sono definiti le caratteristiche di una persona sono definiti gli attributi nome, cognome e data di nascita in formato stringa, poi i metodi per impostare singolarmente gli attributi le “setter” che sono di tipo void e le “getter” che sono metodi pubblici per leggere gli attributi. E’ stato definito il metodo Stampa per stampare i dati.
Nella sottoclasse “Studente” sono astati aggiunti gli attributi classe di tipo stringa, la media dei voti che deve essere calcolata con il metodo “CalcolaMedia()” a partire dal vettore dei voti. E’ definito poi il metodo “setVoto” e “getVoto” che permettono la lettura e scrittura dei voti nell’array definito.
Per la gestione dei voti dello studente utilizziamo un vettore dinamico implementato con la libreria STL <vector>.

Codice delle classi Persona e Studente

#include <iostream>
#include <string>
using namespace std;
class Persona
{
    private:
        string nome;
        string cognome;
        string data_nascita;
    public:
    Persona(string n, string c, string d)
    {
        nome=n;
        cognome=c;
        data_nascita=d;
    }
    string getNome()
    {
        return nome;
    }
    string getCognome()
    {
        return cognome;
    }
    string getDataNascita()
    {
        return data_nascita;
    }
    void setNome(string x)
    {
        nome=x;
    }
    void setCognome(string x)
    {
        cognome=x;
    }
    void setDataNascita(string x)
    {
        data_nascita=x;
    }
    void Stampa()
    {
        cout << "Dati Peronsa:\n";
        cout << "Cognome:"<<cognome<<endl;
        cout << "Nome:"<<nome<<endl;
        cout << "Data di Nascita:"<<data_nascita<<endl;
    }
};

La classe Persona è molto semplice sono stati definiti gli attributi, il metodo costruttore, le “setter” e le “getter” oltre che il metodo stampa di tipo void.
Il codice della classe “Studente”

#include "Persona.cpp"
#include <vector>
using namespace std;
class Studente: Persona
{
    private:
        string classe;
        float media;
        vector<float> voti;
    public:
        Studente(string x, string y, string w, string c)
        :Persona( x, y, w)
        {
            classe=c;
            media=0;
        }
        void setVoto(float x)
        {
                voti.push_back(x);
        }
        float getVoto(int x)
        {
            return voti.at(x);
        }
        string getClasse()
        {
            return classe;
        }
        void setClasse(string x)
        {
            classe=x;
        }
        float CalcolaMedia()
        {
            int k;
            float m=0;
            for (k=0;k<voti.size();k++)
                m+=voti.at(k);
            m=m/(voti.size());
  
            return m;
        }
        void Stampa()
        {
            int k;
            cout <<"Dati Studente:"<< endl;
            cout << "Nome"<<getNome()<< endl;
            cout << "cognome:"<<getCognome()<< endl;
            cout << "Data di Nascita:"<< getDataNascita()<< endl;
            cout<<"Media dei Voti:"<< CalcolaMedia()<< endl;
        }
};

Nella classe Studente con un override è stato ridefinito il metodo “Stampa” è stato poi definito il metodo costruttore derivato dal costruttore della superclasse “Persona” ed è stato incluso il metodo per aggiungere un voto al vettore dinamico con il metodo “puls_back” e il metodo “at” per leggere un valore dal vettore dinamico.
Il main può essere inserito nella seconda classe per testare, il codice di esempio è:

int main()
{
    Studente st("Nario","Rossi","15-04-2007","terza f");
    char risp='n';
    float v;
    do
    {
        cout << "\n Inserisci voto studente:";
        cin >> v;
        st.setVoto(v);
        cout << "\n Altri voti s/n ?";
        cin >> risp;
    } while (risp=='s');
    st.Stampa();
    cout << "Media dei voti:"<< st.CalcolaMedia()<<endl;
    return 0;
}

E’ definito un oggetto di nome “st” della classe Studente con valori costanti, sono richiesti i voti durante l’esecuzione del metodo “setVoto” il quale è inserito in un ciclo indefinito post condizionale “do .. while” che continua l’invocazione della setvoto fin quando l’utnte non risponde “n” alla domanda che richiede all’utente di inserire voti.