ereditarietà in c++

22
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11 Ereditarietà in C++

Upload: sorley

Post on 30-Jan-2016

50 views

Category:

Documents


0 download

DESCRIPTION

Ereditarietà in C++. Specializzazione e inclusione. quindi. S’ è incluso in S perché la definizione di S’ specializza quella di S. Avremmo potuto definire S’ come:. Specializzazione e algebre. Un gruppo G = (S, +, 0,  ) è una struttura tale che … - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

Ereditarietà in C++

Page 2: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

Specializzazione e inclusione

)}()(:{

)}(:{

xQxPxS

xPxS

quindi

SS Avremmo potuto definire S’ come:

)}(:{ xQSxxS

S’ è incluso in S perché la definizione di S’ specializza

quella di S

Page 3: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

Specializzazione e algebre

Un gruppo G = (S, +, 0, ) è una struttura tale che …

Un anello A = (S, +, 0, , ) è una struttura tale che:

1. (S, +, 0, ) sia un gruppo commutativo

2. distribuisca su +

Un anello è un gruppo con opportune proprietà cui si aggiunge una nuova operazione (il prodotto).

Page 4: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

Gerarchie di specializzazione

Membro-Università

AmministrativoStudente-Triennio

Studente-Biennio

DottorandoDocente

Ordinario Associato Ricercatore

Dipendente Studente

Page 5: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

Gerarchie di specializzazione

Figura

Figura2D Figura3D

Cerchio

Triangolo

QuadratoSfera

CuboTetraedro

Page 6: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

Classi base e classi derivate

• Se A deriva da B allora A è sottoclasse di B.• Il processo di ideazione e realizzazione di un programma

può vedersi come definizione di classi per progressivi specializzazione e reffinamento di una a più classi base

Classe base: classe utilizzata per definire ulteriori specializzazioni

Classe derivata: classe ottenuta per specializzazione di una o più classi

Classe base: classe utilizzata per definire ulteriori specializzazioni

Classe derivata: classe ottenuta per specializzazione di una o più classi

Page 7: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

Classi base e classi derivate

class Point2D {

private:

double x, y;

public:

Point2D (double a, double b);

void SetX( double a);

void SetY( double b);

double GetX() const { return x;}

double GetY() const { return y;}

};

Page 8: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

Classi base e classi derivate

class Point3D : public Point2D {

private:

double z;

public:

Point3D (double a, double b, double c);

void SetZ( double c);

double GetZ() const { return z;}

};

Classe derivata dalla classe base Point2D

Una classe derivata possiede tutti i membri della classe base, cui se ne aggiungono degli altri.

Page 9: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

La relazione “è un”: sottotipo

Se Y è derivata di X, allora ogni oggetto di classe Y è un oggetto di classe X

Se Y è derivata di X, allora ogni oggetto di classe Y è un oggetto di classe X

Point3D p(1.0, 4.5, 0.0);

cout << p.GetX(); // stampa 1

cout << p.GetZ(); // stampa 0

Point2D* pt = &p; // p è usato come Point2D

pt->SetY(3);

cout << p.GetY(); // stampa 3

double x = pt->GetZ(); // errore di tipo!!

Page 10: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

Visibilità

class Point2D {

private:

double x, y;

public:

}

class Point3D : public Point2D {

private:

double z;

public: ...

double bump() const { return x;} // errore

};

x è un campo privato della classe base

Page 11: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

Visibilità

class Point2D {

protected:

double x, y;

public:

}

class Point3D : public Point2D {

private:

double z;

public: ...

double bump() const { return x;} // ok!

};

x è un campo “protected” della

classe base

I campi “protected” sono visibili alla classe base ed

a tutte le sue derivate

Page 12: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

Visibilità

Nella derivazione “public”:• i membri pubblici sono ovunque visibili;• i membri privati sono visibili solo nella classe cui appartengono;• i membri protected sono visibili nella classe cui appartengono ed in tutte le sue derivate.

Nella derivazione “public”:• i membri pubblici sono ovunque visibili;• i membri privati sono visibili solo nella classe cui appartengono;• i membri protected sono visibili nella classe cui appartengono ed in tutte le sue derivate.

La modalità protected viola la regola di incapsulamento

Page 13: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

Overriding

class Point2D {

public: ...

void print();

};

void Point2D::print()

{ cout << x << ',' << y;

}

class Point3D {

public: ...

void print();

};

void Point3D::print()

{ cout << GetX() << ',' << GetY() << ',' << z;

}

La nuova definizione di print()

sostituisce la vecchia per i punti 3D

Page 14: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

Overriding

void Point3D::print()

{ Point2D::print();

// chiama la funzione print della classe base

cout << ',' << z;

}

La vecchia definizione di print() può essere usata nella nuova, ma si deve usare

la risoluzione dello scope

Page 15: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

Overriding

Una classe derivata può ridefinire un metodo (funzione membro) della classe base; la nuova versione deve

avere lo stesso nome la stessa segnatura.

Una classe derivata può ridefinire un metodo (funzione membro) della classe base; la nuova versione deve

avere lo stesso nome la stessa segnatura.

Overriding: specializzazione dei metodi per gli oggetti di una classe derivata;

contrapposto a

Overloading: varianti di un metodo in funzione della segnatura.

Page 16: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

Costruttori

class Point2D {

protected:

double x, y;

public:

Point2D (double a, double b) :

x(a), y(b) {};

...

}; Costruttore analogo a:

Point2D (double a, double b)

{ x = a; y = b;}

Page 17: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

Costruttori

Point3D (double a, double b, double c) :

Point2D(a,b) { z = c;}

oppure

Point3D (double a, double b, double c) :

Point2D(a,b), z(c) {}

In ogni caso il costruttore della classe base deve essere usato, e viene eseguito prima di quello della

classe derivata

Page 18: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

La relazione “ha un”

template <class T> class Stack {

private:

List<T> s;

public:

void push(T x) { s.InsertAtFront(x);}

void pop (T& x){ s.RemoveFirst(x); }

bool IsEmpty() { return s.IsEmpty();}

};

Page 19: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

La relazione “implementa in termini di”

template <class T>

class Stack : private List<T> {

public:

void push(T x) { InsertAtFront(x);}

void pop (T& x){ RemoveFirst(x); }

bool IsEmpty() { return IsEmpty();}

};

Page 20: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

Visibilità dei campi nelle derivazioni public e private

class A {private: int x;protected: int y;public: int z;

};class B : private A {

private: int a;protected: int b;public: c;// x non e’ accessibile; y e z lo sono

};class C : public B {

public:// non sono accessibili x, y, z, a,// sono accessibili b, c

};

ha l’effetto di rendere privati tutti i campi di classe A per gli oggetti di classe C (sottoclasse di B)

Page 21: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

Legami statici e dinamici

class Strumentista {

public: void chisono (){cout << “un strumentista”;

virtual void cosasuono()

{cout << “uno strumento”; }

}

class Violinista: public Strimentista {

public: void chisono (){cout << “un violinista”;

void cosasuono() {cout << “il violino”; }

}

Violinista v; Strumentista *ps = &v;

ps->chisono(); // stampa “un strumentista”

Ps->cosasuono(); // stampa “il violino”

Page 22: Ereditarietà in C++

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 11

Funzioni virtuali e classi astratteIl C++ ha legame statico, per ottenere gli effetti del legame dinamico i metodi che possono essere ridefiniti nelle sottoclassi devono essere preceduti da virtualclass A { private: int x;

public: virtual void f(){x = 0};}class B : public A { private: int y;

public void f() {y = 1;}A a; B b;A* p = &a; p->f(); // pone a.x = 0p = &b;p->f(); // pone b.y = 1

Una classe è astratta se contiene almeno un metodo virtuale puro, ossia (essenzialmente) privo di corpo

virtual void g() = 0; // funzione virtuale pura

è usata solo come classe base e non per produrre oggetti e definisce un’interfaccia .