Dziedziczenie wielobazowe. dana klasa może mieć kilka bezpośrednich klas bazowych: dana klasa może mieć kilka bezpośrednich klas bazowych: kolorpołożenie.

Slides:



Advertisements
Podobne prezentacje
Tablice 1. Deklaracja tablicy
Advertisements

C++ wykład 2 ( ) Klasy i obiekty.
C++ wykład 4 ( ) Przeciążanie operatorów.
Język C/C++ Funkcje.
Programowanie obiektowe
Programowanie obiektowe PO PO - LAB 2 Wojciech Pieprzyca.
Deklaracje i definicje klas w C++ Składowe, pola, metody Konstruktory
Programowanie obiektowe
Programowanie obiektowe
Metody wirtualne.
Wzorce.
Prowadzący: mgr inż. Elżbieta Majka
Static, const, volatile.
Dziedziczenie. Po co nam dziedziczenie? class osoba { char * imie, char * imie, * nazwisko; * nazwisko;public: void wypisz_imie(); void wypisz_imie();
Programowanie w środowisku sieciowym
Programowanie obiektowe w Javie
Szablony (wzorce) Przykład 1: Szablon klasy -
OOPC++ - wstêp, klasy1 Klasy Do struktury można dołączyć operacje działające na jej polach. struct date { int day, month, year; void set (int d, int m,
Licznik template<class Count_Type> class Count { public:
OOP - programowanie zorientowane obiektowo w VB.NET
Serwery Aplikacji ASP .NET Web Objects Arkadiusz Popa.
DZIEDZICZENIE · klasy bazowe i klasy pochodne WyświetlAutora( ) Autor
Struktury.
Tablice.
C++ wykład 5 ( ) Dziedziczenie.
C++ wykład 6 ( ) Polimorfizm.
C++ wykład 2 ( ) Klasy i obiekty.
Zasady zaliczenia Warunki uzyskania zaliczenia:
Typy pochodne 1 Często dogodnie jest wprowadzić nowy typ, który jest podobny do istniejącego, niemniej jednak różny. Niech T będzie pewnym typem. Możemy.
Klasy w C++. Deklaracja klasy class NazwaTwojejKlasy { //w tym miejscu piszemy definicje typów, //zmienne i funkcje jakie mają należeć do klasy. }; //tutaj.
struct nazwa { lista składników }; Dostęp do składowych struktury Nazwa_Zmniennej_Strukturalnej. Nazwa_Składnika.
Podstawy programowania II
T: Różnice pomiędzy programowaniem strukturalnym a obiektowym
Programowanie obiektowe III rok EiT
Programowanie obiektowe III rok EiT dr inż. Jerzy Kotowski Wykład XIII.
Andrzej Repak Nr albumu
Java – coś na temat Klas Piotr Rosik
Dziedziczenie Marek Serek Dziedziczenie Dziedziczenie to jeden z fundamentów programowania obiektowego. Umożliwia sprawne i łatwe wykorzystywanie.
Dziedziczenie Maciek Mięczakowski
Inicjalizacja i sprzątanie
Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21 Dariusz Wardowski.
Programowanie obiektowe Wykład 6 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/14 Dariusz Wardowski.
Programowanie obiektowe 2013/2014
Prasek Aneta, Skiba Katarzyna. Funkcje stałe const to takie funkcje, które nie mogą modyfikować stanu obiektu. Oznacza to, że funkcja stała nie może zmieniać.
Kurs języka C++ – wykład 3 ( )
Programowanie w języku C++
Kurs języka C++ – wykład 5 ( )
Treści multimedialne - kodowanie, przetwarzanie, prezentacja Odtwarzanie treści multimedialnych Andrzej Majkowski informatyka +
Programowanie strukturalne i obiektowe C++
Kurs języka C++ – wykład 4 ( )
K URS JĘZYKA C++ – WYKŁAD 2 ( ) Klasy i obiekty.
K URS JĘZYKA C++ – WYKŁAD 6 ( ) Polimorfizm.
Klasy ( uzupełnienie ). Definicja klasy Klasa jest zbiorem logicznie powiązanych danych i funkcji, przeznaczonych do realizacji konkretnego zadania; Zamknięcie.
Programowanie obiektowe Wykład 9 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/15 Dariusz Wardowski.
Przeładowanie funkcji. Dotychczas wiedzieliśmy, że: w danym zakresie ważności może być tylko jedna funkcja o danej nazwie. Kompilator języka C++ daje.
Programowanie Zaawansowane
Dziedziczenie Wykład 7 Dziedziczenie sekwencyjne
PO13-1 / 19 Wykład 13 Wyjątki i ich zgłaszanie Wyłapywanie wyjątków Obsługa wyjątków Wykorzystanie polimorfizmu Filtrowanie wyjątków Błędy w konstruktorach.
Partnerstwo dla Przyszłości 1 Lekcja 28 Dziedziczenie i rodzaje dziedziczenia.
Podstawy informatyki Funkcje Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi.
K URS JĘZYKA C++ – WYKŁAD 3 ( ) Przenoszenie Składowe statyczne Funkcje wbudowane Argumenty domyślne.
C++ mgr inż. Tomasz Turba Politechnika Opolska 2016.
Programowanie Obiektowe – Wykład 6
Kurs języka C++ – wykład 3 ( )
Klasy, pola, obiekty, metody. Modyfikatory dostępu, hermetyzacja
Delegaty Delegat to obiekt „wiedzący”, jak wywołać metodę.
Programowanie Obiektowe – Wykład 2
Kurs języka C++ – wykład 4 ( )
Zapis prezentacji:

Dziedziczenie wielobazowe

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

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

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 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 dwukropek w deklaracji występuje tylko raz, potem przecinki wszystkie klasy bazowe muszą być w całości zdefiniowane wszystkie klasy bazowe muszą być w całości zdefiniowane nie wystarczy definicja nazwy klasy bazowej (class C) 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. w ten sposób wykluczamy zapętlenie w dziedziczeniu – klasa nie może być własnym przodkiem.

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 konstruktory klas bazowych wywoływane są w kolejności takiej, w jakiej zadeklarowano klasy bazowe w deklaracji danej klasy 1. kolor() 2. położenie()

Niejednoznaczności Występują gdy takie same nazwy pól lub metod odziedziczone są po więcej niż jednej bezpośredniej klasie bazowej. 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

Niejednoznaczności punkt zawiera pola: kolor::kpołożenie::k kolor::nazwapołożenie::j odwołania w zakresie klasy punkt: 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) 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ść. najpierw jest sprawdzana jednoznaczność, potem dostępność. żeby uniknąć niejednoznaczności należy podać, operatorem zakresu, przodka od którego nazwa pochodzi żeby uniknąć niejednoznaczności należy podać, operatorem zakresu, przodka od którego nazwa pochodzi

Niejednoznaczności class kj {public: int k,j}; class odcinek: public punkt, public polozenie {}; klasa odcinek zawiera pola: klasa odcinek zawiera pola: punkt::kolor::kkj::k punkt::kolor::nazwa kj::j punkt::położenie::kpunkt::położenie::j odwołując się do nazwy, trzeba podać zakres, w którym jest jednoznaczna: 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

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

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

Wielokrotne wystąpienia tej samej klasy bazowej okno okno okno okno o_z ramkąo_z_menu o_z_ramka_i_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{};

Wirtualne klasy bazowe okno okno o_z ramkąo_z_menu o_z_ramka_i_menu o_z_ramka_i_menu

Wirtualne klasy bazowe - deklarowanie okno okno o_z ramkąo_z_menu o_z_ramka_i_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{}; 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 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. wystarczy żeby bezpośredni potomek dziedziczył wirtualnie – o_z_ramka_i_menu już nie musi.

Ograniczenia dostępu do odziedziczonych pól jeżeli pola wirtualnej klasy bazowej są 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 jeżeli pola wirtualnej klasy bazowej są 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 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: przykład: class o_z_ramka:private virtual 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

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

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. 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. 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. 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. UWAGA: jeżeli nie opisze się wywołania się konstruktora wirtualnej klasy bazowej jawnie to zostanie zastosowany konstruktor domniemany.

Wielokrotne wywoływanie metod klasy bazowej okno okno o_z ramkąo_z_menu o_z_ramka_i_menu o_z_ramka_i_menu każda klasa ma metodę rysuj(); każda klasa ma metodę rysuj(); metoda rysuj() danej klasy wywołuje metodę rysuj() przodka; 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() wywoła metody rysuj() obu przodków; o_z_ramka_i_menu::rysuj() pośrednio wywoła dwukrotnie okno::rysuj(); o_z_ramka_i_menu::rysuj() pośrednio wywoła dwukrotnie okno::rysuj();

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(); _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_ramka::_rysuj(); o_z_menu::_rysuj(); o_z_menu::_rysuj(); _rysuj _rysuj}

Klasa bazowa wirtualna i nie- wirtualna okno okno okno okno o_z ramkąo_z_menu o_z_ramka_i_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 {}; :public o_z_ramka, public o_z_menu {}; dana klasa może być jednocześnie dziedziczona wirtualnie i nie-wirtualnie dana klasa może być jednocześnie dziedziczona wirtualnie i nie-wirtualnie UWAGA: bezpośredni przodek nie- wirtualny nie może jednocześnie być przodkiem niebezpośrednim – niejednoznaczność UWAGA: bezpośredni przodek nie- wirtualny nie może jednocześnie być przodkiem niebezpośrednim – niejednoznaczność