Differences

This shows you the differences between two versions of the page.

Link to this comparison view

poo-is:laboratoare:08 [2020/09/29 14:43]
eduard.ciurezu [Interfete]
— (current)
Line 1: Line 1:
-===== Laboratorul 08: Mostenire multipla. Clase si functii abstracte. Interfete ===== 
  
-In cadrul acestui laborator, vom discuta despre **mostenirea multipla** si ambiguitatile care pot aparea o data cu aceasta, despre **clasele si functiile abstracte** si despre **interfete**,​ cu ajutorul carora vom reusi sa aprofundam cunostintele legate de derivarea claselor si suprascrierea metodelor acestora. 
- 
-Ca referinte externe, recomandam urmatoarele sectiuni din [[https://​discourse-production.oss-cn-shanghai.aliyuncs.com/​original/​3X/​2/​3/​2380479dcb8e375425884a10da232730bbc7f88d.pdf|Absolute C++]]: 
-  * Abstract Classes and Pure Virtual Functions (pag. 671-673) 
-  * Separate Interface and Implementation (pag. 264-265) 
- 
-====== Mostenire Multipla ====== 
-Spre deosebire de multe alte limbaje de programare orientate-obiect,​ C++ permite **mostenirea multipla** (o clasa poate fi derivata din mai multe clase de baza). 
-<​note>​In acest caz, la declararea clasei derivate nu se specifica o singura clasa de baza, ci o succesiune de clase de baza, separate prin virgula, avand in fata specificatorii de acces.</​note>​ 
-<​code>​class C:public A, public B</​code>​ 
-<​note>​In candrul mostenirii multiple, **constructorii** claselor de baza vor fi apelati in ordinea enumerarii, iar **destructorii** vor fi apelati in ordine inversa.</​note>​ 
- 
-===== Problema Diamantului ===== 
-Desi mostenirea multipla pare a fi un procedeu util, aceasta poate duce la multe ambiguitati,​ cea mai mare dintre acestea fiind **Problema Diamantului** (numita si **“death diamond”**). Sa consideram urmatoarea ierarhie de clase: 
- 
-{{ :​poo-is:​laboratoare:​ierarhie-clase-diamant.png?​300 |}} 
- 
-In acest exemplu, avem o clasa de baza numita **LivingThing** avand metoda **breathe()**. Clasele **Animal** si **Reptile** mostenesc clasa **LivingThing** si suprascriu in moduri diferite metoda **breathe()**. Clasa **Snake** mosteneste ambele clase, **Animal** si **Reptile**,​ insa nu suprascrie metoda **breathe()**. 
- 
-<note important>​In momentul de fata, daca apelam metoda **breathe()** din **Snake**, acesta nu va sti ce metoda sa apeleze, daca sa fie cea suprascrisa in clasa **Animal** sau cea suprascrisa in clasa **Reptile**.</​note>​ 
- 
-<note tip>Cum rezolvam insa Problema Diamantului?​ Folosind **derivarea virtuala**. 
-<​code>​class Animal: virtual public LivingThing 
-class Reptile: virtual public LivingThing</​code></​note>​ 
- 
-Clasele de baza virtuale sunt utile in cadrul mostenirii multiple cand o serie de clase sunt derivate din aceeasi clasa de baza, iar aceasta urmeaza a fi clase parinte pentru o alta clasa. 
- 
-Efectul acestei mosteniri virtuale nu este sesizat in clasele **Animal** si **Reptile**,​ ci se observa in urmatorul nivel de derivare, clasa **Snake**. 
- 
-<​note>​Pentru a se crea un obiect de tip **Snake**, se vor apela constructorii claselor **Animal** and **Reptile**,​ dar se va apela o singura data constructorul clasei **LivingThing**,​ astfel **Snake** va avea o singura instanta a clasei **LivingThing**.</​note>​ 
- 
-====== Clase si Functii Abstracte ====== 
- 
-O metoda virtuala se numeste **abstracta (pura)** daca nu are implementare:​ 
-<​code>​virtual tip_returnat metoda(lista parametrii) = 0;</​code>​ 
-<​note>​O clasa se numeste **abstracta** daca are cel putin **o metoda abstracta**.</​note>​ 
- 
-Uneori implementarea tuturor functiilor dintr-o clasa de baza nu poate fi realizata, deoarece nu stim cu certitudine implementarea acestora. Sa presupunem ca avem o clasa de baza **Shape**. Nu putem implementa metoda **draw()** in **Shape**, insa stim cu siguranta ca fiecare clasa derivata o sa aiba aceasta metoda implementata. 
- 
-<code c++ Shape.cpp>​ 
-#include <​iostream>​ 
-using namespace std; 
- 
-//Clasa abstracta 
-class Shape { 
-    //Membrii clasei 
-    protected: 
-        int id; 
-    public: 
-        //Functie abstracta 
-        virtual void draw() = 0; 
-}; 
- 
-//Clasa care mosteneste Shape si implementeaza draw 
-class Circle: public Shape { 
-    public: 
-        void draw() { cout << "DRAW CIRCLE!"​ << endl; } 
-}; 
- 
-int main () { 
-    Circle c; 
-    c.draw(); ​  //Se va afisa DRAW CIRCLE! 
-    return 0; 
-} 
-</​code>​ 
- 
-<note important>​ 
-  * Functiile abstracte sunt folosite in cazul in care metoda nu are o implementare in clasa de baza, insa dorim sa o declaram virtuala. 
-  * Nu se pot instantia obiecte de tipul unei clase abstracte, **DAR** se pot declara pointeri de acel tip. 
-  * Suntem obligati, ca eventual, sa implementam functia intr-o clasa derivata, altfel, si aceasta clasa derivata o sa fie tot abstracta. 
-</​note>​ 
- 
-====== Interfete ====== 
- 
-<​note>​O clasa fara atribute si cu toate metodele abstracte se numeste **interfata**.</​note>​ 
- 
-Interfetele si clasele abstracte sunt foarte importante pentru dezvoltarea ierarhiilor de clase – acestea reprezinta **o schita** a ceea ce trebuie implementat/​suprascris in clasele derivate. 
- 
-Clasele derivate din una sau mai multe interfete sunt obligate ca, eventual, sa furnizeze implementari pentru toate metodele abstracte. 
- 
-Ca exemplu, consideram urmatoarea interfata **Shape**, cu metodele abstracte **perimeter()** si **area()**. Avand in vedere faptul ca, pentru fiecare figura geometrica in parte exista alte formule pentru calculul perimetrului si al ariei, fiecare clasa derivata va avea propria implementare pentru cele doua metode. 
- 
-<code c++> 
-//Interfata 
-class Shape { 
-    //Nu are atribute, toate metodele sunt abstracte 
-    public: 
-        virtual double perimeter() = 0; 
-        virtual double area() = 0; 
-}; 
- 
-//Clasa care implementeaza interfata Shape 
-class Square: public Shape { 
-    protected: 
-        double L; 
-    public: 
-        double perimeter() { return 4 * L; } 
-        double area() { return L * L; } 
-}; 
- 
-//Alta clasa care implementeaza interfata Shape 
-class Circle: public Shape { 
-    protected: 
-        double R; 
-    public: 
-        double perimeter() { return 2 * 3.14 * R; } 
-        double area() { return 3.14 * R * R; } 
-}; 
-</​code>​ 
poo-is/laboratoare/08.1601379802.txt.gz · Last modified: 2020/09/29 14:43 by eduard.ciurezu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0