Introduzione Le due componenti principali dei programmi


Può essere necessario assegnare la funzione al messaggio a run-time (late binding)



Scaricare 584 b.
Pagina8/9
13.12.2017
Dimensione del file584 b.
1   2   3   4   5   6   7   8   9

Può essere necessario assegnare la funzione al messaggio a run-time (late binding)

  • Polimorfismo



  • Controllo dei tipi

    • Controllare i tipi significa verificare che ad un oggetto vengano inviati solo messaggi che è in grado di comprendere:

      • controllo del nome del metodo
      • controllo della lista degli argomenti
    • In C++ il controllo è fatto dal compilatore (strong typing)

    • In altri linguaggi (ad esempio SmallTalk) è fatto a run-time (weak typing)



    Typing & Binding



    Esempio: i soldati

    • Tutti i soldati devono capire il messaggio attacca. Il messaggio ha conseguenze diverse a seconda del tipo di soldato:

    • Il gestore della schermata vuole tenere una lista di soldati e vuole poter dire ad ogni soldato di attaccare indipendentemente dal tipo ma basandosi solo sulla posizione.



    list lista;

    • list lista;

    • riempiLista(lista);

    • Posizione unaPosizione=...;

    • list::iterator iter;

    • for(iter=lista.begin();iter!=lista.end();iter++){

    • Soldato unSoldato=(*iter);

    • if(unSoldato.posizione()==unaPosizione) unSoldato.attacca();

    • }

    • class Soldato {

    • void attacca() {

    • // cosa scrivo qui?!? Per quale tipo di

    • // soldato implemento il metodo attacca()?

    • }

    • };



    Polimorfismo

    • Polimorfismo con tipi controllati dal compilatore (Strong typing & late binding).

    • Come?

    • In C++ viene implementato tramite il concetto di ereditarietà (inheritance)

    • Classe astratta: definisce i messaggi

    • Classe concreta: assegna i metodi ai messaggi

    • La classe concreta eredita da quella astratta



    Ereditarietà

    • Una classe può essere derivata da una classe esistente usando la sintassi:

    • Se la classe base non ha un costruttore di default:

      • La classe derivata deve implementarlo
    • Se la classe base ha un costruttore di default:

      • il costruttore della classe derivata deve esplicitamente invocarlo nella sua lista di inizializzatione
        • Il costruttore della classe base può così essere eseguito prima che il costruttore della classe derivata sia eseguito


    Ereditarietà (2)

    • Una classe derivata pubblicamente è a tutti gli effetti un sottotipo della classe base.

      • Un oggetto della classe derivata può essere trattato come se fosse un oggetto della classe base
      • Un puntatore alla classe base può puntare ad oggetti della classe derivata
      • Un riferimento alla classe derivata può, se la cosa ha un senso, essere implicitamente convertito ad un riferimento alla classe base
      • E` possibile dichiarare un riferimento alla classe base ed inizializzarlo ad un oggetto della classe derivata


    Ereditarietà (3)

    • La definizione dell’interfaccia (metodi pubblici) della classe base è estremamente importante perchè determina il comportamento delle classi derivate

    • Un metodo della classe base può essere:

      • dichiarato e definito normalmente
        • la classe derivata eredita questo metodo e NON può ridefinirlo
      • dichiarato virtual e definito normalmente
        • la classe derivata eredita questo metodo e può ridefinirlo
      • dichiarato virtual e non definito (=0)


    Classi base astratte

    • Una funzione puramente virtuale è un metodo virtuale non definito. E` dichiarato come:

    • Una classe che ha almeno un metodo puramente virtuale è chiamata classe astratta

    • Oggetti di una classe astratta non possono esistere

    • Puntatori ad una classe base astratta possono essere definiti ed usati polimorficamente (per puntare ad oggetti delle classi derivate)

    • Una classe base astratta viene introdotta per specificare l’interfaccia di una categoria di classi



    class Soldato {

    • class Soldato {

    • virtual void attacca()=0;

    • };

    • class Arcere : public Soldato {

    • virtual void attacca() {

    • // lancia una freccia

    • }

    • };

    • class Fante : public Soldato {

    • virtual void attacca() {



    1   2   3   4   5   6   7   8   9


    ©astratto.info 2017
    invia messaggio

        Pagina principale