1 / 19

Dziedziczenie wielobazowe

Dziedziczenie wielobazowe. Dziedziczenie wielobazowe. dana klasa może mieć kilka bezpośrednich klas bazowych : kolor położenie punkt dziedziczenie wielobazowe to sposób , w jaki programista opisuje obiekty które łączą cechy różnych klas. Dziedziczenie wielobazowe.

kairos
Download Presentation

Dziedziczenie wielobazowe

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Dziedziczenie wielobazowe

  2. Dziedziczenie wielobazowe • dana klasa może mieć kilka bezpośrednich klas bazowych: kolorpołożenie punkt • dziedziczenie wielobazowe to sposób, w jaki programista opisuje obiekty które łączą cechy różnych klas.

  3. Dziedziczenie wielobazowe • dana klasa może mieć kilka bezpośrednich klas bazowych: kolorpołożenie punkt class kolor {}; class położenie {}; class punkt: public kolor, public położenie { ... };

  4. Deklaracja klasy pochodnej class punkt: public kolor, public położenie { ... }; • domyślnie dziedziczymy prywatnie, jeżeli chcemy publicznie to zadeklarujmy to jawnie dla każdej z klas bazowych, która ma być przodkiem publicznym • dwukropek w deklaracji występuje tylko raz, potem przecinki • wszystkie klasy bazowe muszą być w całości zdefiniowane • nie wystarczy definicja nazwy klasy bazowej (class C) • w ten sposób wykluczamy zapętlenie w dziedziczeniu – klasa nie może być własnym przodkiem.

  5. Konstruktory klas bazowych class punkt: public kolor, public położenie { ... }; • konstruktory klas bazowych wywoływane są w kolejności takiej, w jakiej zadeklarowano klasy bazowe w deklaracji danej klasy • kolor() • położenie()

  6. Niejednoznaczności • Występują gdy takie same nazwy pól lub metod odziedziczone są po więcej niż jednej bezpośredniej klasie bazowej. class kolor {public: int k; char *nazwa}; class położenie { public: int k; int j }; class punkt: public kolor, public położenie { ... }; punkt zawiera pola: kolor::kpołożenie::k kolor::nazwapołożenie::j

  7. Niejednoznaczności punkt zawiera pola: kolor::kpołożenie::k kolor::nazwapołożenie::j • odwołania w zakresie klasy punkt: punkt::nazwa; // OK punkt::j; // OK // punkt::k — błąd • taki błąd wystąpi również gdy jest tylko jedna dostępna nazwa (gdy np. pozostałe są prywatnymi składowymi klas) • najpierw jest sprawdzana jednoznaczność, potem dostępność. • żeby uniknąć niejednoznaczności należy podać, operatorem zakresu, przodka od którego nazwa pochodzi

  8. Niejednoznaczności class kj {public: int k,j}; class odcinek: public punkt, public polozenie {}; • klasa odcinek zawiera pola: punkt::kolor::kkj::k punkt::kolor::nazwakj::j punkt::położenie::k punkt::położenie::j • odwołując się do nazwy, trzeba podać zakres, w którym jest jednoznaczna: odcinek::nazwa→ odcinek::punkt::kolor::nazwa położenie::j → odcinek::punkt::położenie::j punkt::j → odcinek::punkt::położenie::j położenie::k→ odcinek::punkt::położenie::k

  9. Niejednoznaczności • Aby zlikwidować niejednoznaczność nazwy można zdefiniować akcesor, którego nazwa przykryje nazwę niejednoznaczną. • np. dla klasy punkt: int & punkt::k(){ return kolor::k; } • użycie: punkt p; p.k()=7; • wewnątrz metod klasy punkt i pochodnych punkt::k() będzie się zachowywać jak pukt::kolor::k • niedoskonałe – bo zmienną zastępujemy metodą, • skuteczne – bo kompilator zoptymalizuje kod

  10. Wielokrotne wystąpienia tej samej klasy bazowej • każdy z bezpośrednich przodków musi występować pojedynczo. • nie wolno: class odcinek: kolor, położenie, położenie {}; • bezpośredniprzodek nie może być równocześnie niebezpośrednim przodkiem. • nie wolno: class odc_2: punkt, położenie {}; • Wniosek: jeżeli potrzebujemy kilku egzemplarzy danej klasy to: • możemy je zawrzeć w klasie, a nie odziedziczyć • możemy je odziedziczyć kilkakrotnie, lecz każdorazowo jako przodka niebezpośredniego

  11. Wielokrotne wystąpienia tej samej klasy bazowej oknookno o_z ramkąo_z_menu o_z_ramka_i_menu class okno{}; class o_z_ramka:public okno{}; class o_z_menu:public okno {}; class o_z_ramka_i_menu:public o_z_ramka, public o_z_menu{};

  12. Wirtualne klasy bazowe okno o_z ramkąo_z_menu o_z_ramka_i_menu

  13. we wszystkich klasach pochodnych dla których chcemy żeby w razie dziedziczenia po kilku z nich ich bezpośrednia klasa bazowa wystąpiła tylko raz należy tę klasę bazową zadeklarować ze słowem kluczowym virtual wystarczy żeby bezpośredni potomek dziedziczył wirtualnie – o_z_ramka_i_menu już nie musi. Wirtualne klasy bazowe - deklarowanie okno o_z ramkąo_z_menu o_z_ramka_i_menu class okno{}; class o_z_ramka:public virtual okno{}; class o_z_menu:public virtual okno {}; class o_z_ramka_i_menu:public o_z_ramka, public o_z_menu{};

  14. Ograniczenia dostępu do odziedziczonych pól • jeżeli pola wirtualnej klasy bazowejsą dostępne przez przynajmniej jedną ze ścieżek wiodących do tej klasy, to można się odwoływać do nich w zakresie klasy potomnej • Oczywiście jeżeli w innej ścieżce jest dziedziczona prywatnie to nie można użyć zakresu w którym jest niewidoczna • przykład: class o_z_ramka:privatevirtual okno{}; o_z_ramka_i_menu::o;// ok., odpowiednik ponizszego o_z_ramka_i_menu::o_z_menu::o; //ok. // o_z_ramka_i_menu::o_z_ramka::o – tutaj prywatne

  15. bezpośredni przodek wirtualnymoże jednocześnie być przodkiem niebezpośrednim – nie ma niejednoznaczności Ograniczenia dostępu do odziedziczonych pól okno o_z ramkąo_z_menu o_z_ramka_i_menu class okno{}; class o_z_ramka:privatevirtual okno{}; class o_z_menu: privatevirtual okno {}; class o_z_ramka_i_menu :public o_z_ramka, public o_z_menu , public virtual okno{};

  16. Kolejność wywołania konstruktorów • przed wszystkimi innymi wywoływane są konstruktory klas bazowych wirtualnych w kolejności od pierwszego wystąpienia w deklaracji kl. pochodnej. • parametry konstruktora dla klasy bazowej wirtualnej można przekazać w konstruktorach wszystkich (nawet niebezpośrednich) klas pochodnych. • Zastosowanie znajdą te parametry, które opisano w liście inicjalizazacyjnej konstruowanej klasy – np. konstruujemy z_ramka_i_menu to parametry konstrukcji okna z listy okna z ramka zostana zignorowane. • UWAGA: jeżeli nie opisze się wywołania się konstruktora wirtualnej klasy bazowej jawnie to zostanie zastosowany konstruktor domniemany.

  17. Wielokrotne wywoływanie metod klasy bazowej okno o_z ramkąo_z_menu o_z_ramka_i_menu • każda klasa ma metodę rysuj(); • metoda rysuj() danej klasy wywołuje metodę rysuj() przodka; • o_z_ramka_i_menu::rysuj() wywoła metody rysuj() obu przodków; • o_z_ramka_i_menu::rysuj() pośrednio wywoła dwukrotnie okno::rysuj();

  18. Wielokrotne wywoływanie metod klasy bazowej void o_z_ramka::_rysuj() { //tu rysowanie właściwe dla ozramka } void o_z_ramka::rysuj() { okno::_rysuj(); _rysuj(); } void o_z_ramka_i_menu::_rysuj() { //tu rysowanie właściwe dla ozramka } void o_z_ramka_i_menu::rysuj() {okno::_rysuj(); o_z_ramka::_rysuj(); o_z_menu::_rysuj(); _rysuj }

  19. dana klasa może być jednocześnie dziedziczona wirtualnie i nie-wirtualnie UWAGA: bezpośredni przodek nie-wirtualnynie może jednocześnie być przodkiem niebezpośrednim –niejednoznaczność Klasa bazowa wirtualna i nie-wirtualna oknookno o_z ramkąo_z_menu o_z_ramka_i_menu class okno{}; class o_z_ramka: public virtual okno{}; class o_z_menu: public okno {};// okno dziedziczone nie-wirtualnie class o_z_ramka_i_menu// tu nie wolno bez virtual: public okno :public o_z_ramka, public o_z_menu {};

More Related