Informatyka 2 - Wydział Elektryczny
Transkrypt
Informatyka 2 - Wydział Elektryczny
Informatyka 2 Politechnika Białostocka - Wydział Elektryczny Elektrotechnika, semestr III, studia niestacjonarne I stopnia Rok akademicki 2012/2013 Wykład nr 6 (07.12.2012) dr inż. Jarosław Forenc Informatyka 2, studia niestacjonarne I stopnia Rok akademicki 2012/2013, Wykład nr 6 Plan wykładu nr 6 Programowanie obiektowe w języku C++ dziedziczenie polimorfizm, funkcje wirtualne dr inż. Jarosław Forenc 2/17 Informatyka 2, studia niestacjonarne I stopnia Rok akademicki 2012/2013, Wykład nr 6 dr inż. Jarosław Forenc 3/17 Dziedziczenie dziedziczenie jest to technika pozwalającą na definiowanie nowej klasy przy wykorzystaniu klasy już istniejącej polega na przejmowaniu jednej klasy (bazowej, podstawowej) przez inną klasę (pochodną) przy dziedziczeniu, w skład obiektów klasy pochodnej automatycznie wchodzą pola klasy bazowej do obiektów klasy pochodnej możemy stosować operacje zdefiniowane przez funkcje składowe klasy bazowej Informatyka 2, studia niestacjonarne I stopnia Rok akademicki 2012/2013, Wykład nr 6 dr inż. Jarosław Forenc 4/17 Dziedziczenie przykładowa klasa podstawowa i klasa pochodna /* klasa podstawowa */ /* klasa pochodna */ class osoba { char *imie; char *nazwisko; int wiek; public: osoba(char *i,char *n,int w); ~osoba() void drukuj(); }; class student : public osoba { char *wydzial; int semestr; public: student(char *i,char *n, int w,char *wy,int s); ~student() void drukuj(); void promocja(); }; Informatyka 2, studia niestacjonarne I stopnia Rok akademicki 2012/2013, Wykład nr 6 dr inż. Jarosław Forenc 5/17 Dziedziczenie w klasie pochodnej można zdefiniować: dodatkowe dane składowe dodatkowe funkcje składowe dane i funkcje o takich samych nazwach jak w klasie podstawowej (dane i funkcje z klasy podstawowej są zasłaniane) jeśli nie podamy sposobu dziedziczenia, to domyślnie będzie to private Informatyka 2, studia niestacjonarne I stopnia Rok akademicki 2012/2013, Wykład nr 6 dr inż. Jarosław Forenc 6/17 Dziedziczenie - sposoby dziedziczenia sposób dziedziczenia klasa podstawowa private protected public private - - - protected private protected protected public private protected public podczas dziedziczenia nie są dziedziczone: konstruktor, destruktor i operator przypisania "=" Przykład: student st1("Jan","Kos",20,"WE",2); st1.drukuj(); st1.osoba::drukuj(); - deklaracja obiektu - wywołanie funkcji z klasy student - wywołanie funkcji z klasy osoba możliwe jest dziedziczenie wielokrotne, tzn. klasa pochodna może być klasą podstawową dla innej klasy Informatyka 2, studia niestacjonarne I stopnia Rok akademicki 2012/2013, Wykład nr 6 dr inż. Jarosław Forenc 7/17 Przykład nr 1 - dziedziczenie (1/4) #include <iostream> #include <cstring> using namespace std; class osoba { private: char *imie; char *nazwisko; int wiek; public: osoba(char*,char*,int); ~osoba(); void drukuj(); }; klasa podstawowa (bazowa) class student : public osoba { private: char *wydzial; int semestr; public: student(char*,char*,int, char*,int); ~student(); void drukuj(); void promocja(); }; klasa pochodna Informatyka 2, studia niestacjonarne I stopnia Rok akademicki 2012/2013, Wykład nr 6 dr inż. Jarosław Forenc 8/17 Przykład nr 1 - dziedziczenie (2/4) osoba::osoba(char *i, char *n, int w) { imie = new char[strlen(i)+1]; nazwisko = new char[strlen(n)+1]; strcpy(imie,i); strcpy(nazwisko,n); wiek = w; } osoba::~osoba() { delete [] imie; delete [] nazwisko; } konstruktor klasy osoba destruktor klasy osoba void osoba::drukuj() { cout << imie << " " << nazwisko; cout << " " << wiek << endl; } Informatyka 2, studia niestacjonarne I stopnia Rok akademicki 2012/2013, Wykład nr 6 dr inż. Jarosław Forenc 9/17 Przykład nr 1 - dziedziczenie (3/4) student::student(char *i,char *n,int w,char *wy,int s) : osoba(i,n,w) { wydzial = new char[strlen(wy)+1]; strcpy(wydzial,wy); semestr = s; konstruktor } klasy student student::~student() { delete [] wydzial; } destruktor void student::drukuj() klasy student { osoba::drukuj(); cout << "Wydzial: " << wydzial; cout << " Semestr: " << semestr << endl; } lista inicjalizacyjna konstruktora klasy student zawierająca wywołanie konstruktora klasy podstawowej (osoba) Informatyka 2, studia niestacjonarne I stopnia Rok akademicki 2012/2013, Wykład nr 6 dr inż. Jarosław Forenc 10/17 Przykład nr 1 - dziedziczenie (4/ (4/4 4) void student::promocja() { semestr++; } jako pierwszy zostanie wywołany konstruktor klasy podstawowej (osoba) a po nim konstruktor klasy pochodnej (student) int main() { student st1("Jan","Kowalski",20,"WE",2); st1.drukuj(); st1.promocja(); st1.drukuj(); st1.osoba::drukuj(); } kolejność wywołania destruktorów jest odwrotna w stosunku do konstruktorów - jako pierwszy jest wywoływany destruktor klasy student, a po nim destruktor klasy osoba Informatyka 2, studia niestacjonarne I stopnia Rok akademicki 2012/2013, Wykład nr 6 dr inż. Jarosław Forenc 11/17 Przykład nr 1 - dziedziczenie (4/ (4/4 4) void student::promocja() { semestr++; } Jan Kowalski 20 Wydzial: WE Semestr: 2 jako pierwszy zostanie wywołany Kowalski 20 konstruktorJan klasy podstawowej WE Semestr: 3 (osoba) a poWydzial: nim konstruktor klasy Jan Kowalski pochodnej (student) 20 int main() { student st1("Jan","Kowalski",20,"WE",2); st1.drukuj(); st1.promocja(); st1.drukuj(); st1.osoba::drukuj(); } kolejność wywołania destruktorów jest odwrotna w stosunku do konstruktorów - jako pierwszy jest wywoływany destruktor klasy student, a po nim destruktor klasy osoba Informatyka 2, studia niestacjonarne I stopnia Rok akademicki 2012/2013, Wykład nr 6 dr inż. Jarosław Forenc 12/17 Funkcje wirtualne (polimorfizm) Przykład: załóżmy, że piszemy program wyświetlający na ekranie różne figury (kwadrat, trójkąt, koło) do wyświetlenia każdej figury stosowana jest oddzielna funkcja, figury powinny być wyświetlane na ekranie w określonej kolejności Problem: jak zorganizować przechowywanie informacji o figurach? jak zorganizować wyświetlanie figur? Rozwiązanie: klasy + dziedziczenie + funkcje wirtualne definiujemy klasę podstawową (figura) oraz trzy klasy pochodne (kwadrat, trojkat, kolo) w klasie podstawowej umieszczamy funkcję void rysuj() poprzedzoną słowem virtual (funkcja ta nic nie robi) w klasach pochodnych umieszczamy funkcje o takich samych nazwach jak w klasie podstawowej - void rysuj() wyświetlające poszczególne figury Informatyka 2, studia niestacjonarne I stopnia Rok akademicki 2012/2013, Wykład nr 6 dr inż. Jarosław Forenc 13/17 Przykład nr 2 - funkcje wirtualne (1/3) #include <iostream> using namespace std; class figura { public: virtual void rysuj() { }; }; klasa podstawowa figura funkcja wirtualna rysuj() Informatyka 2, studia niestacjonarne I stopnia Rok akademicki 2012/2013, Wykład nr 6 dr inż. Jarosław Forenc 14/17 Przykład nr 2 - funkcje wirtualne (2/3) class kwadrat : public figura klasa pochodna kwadrat { public: void rysuj() { cout << "Kwadrat" << endl; } }; class trojkat : public figura klasa pochodna trojkat { public: void rysuj() { cout << "Trojkat" << endl; } }; class kolo : public figura klasa pochodna kolo { public: void rysuj() { cout << "Kolo" << endl; } }; Informatyka 2, studia niestacjonarne I stopnia Rok akademicki 2012/2013, Wykład nr 6 dr inż. Jarosław Forenc 15/17 Funkcje wirtualne (polimorfizm) jeśli wskaźnikowi do klasy podstawowej (figura) przypiszemy adres obiektu klasy pochodnej (kwadrat, trojkat, kolo), to wywołując poprzez wskaźnik funkcję rysuj(), wywołamy funkcję odpowiadającą danemu obiektowi, np. figura *ptr; kwadrat kw1; trojkat tr1; kolo kol1; - deklaracja deklaracja deklaracja deklaracja wskaźnika do obiektu klasy figura obiektu klasy kwadrat obiektu klasy trojkat obiektu klasy kolo ptr = &kw1; ptr->rysuj(); - wywołana zostanie funkcja rysuj() z klasy kwadrat ptr = &tr1; ptr->rysuj(); - wywołana zostanie funkcja rysuj() z klasy trojkat ptr = &kol1; ptr->rysuj(); - wywołana zostanie funkcja rysuj() z klasy kolo mówimy, że w powyższym przykładzie wystąpił polimorfizm (wielopostaciowość) Informatyka 2, studia niestacjonarne I stopnia Rok akademicki 2012/2013, Wykład nr 6 dr inż. Jarosław Forenc 16/17 Przykład nr 2 - funkcje wirtualne (3/ (3/3 3) int main() { kwadrat trojkat kolo figura lista[0] lista[1] lista[2] lista[3] lista[4] lista[5] kwadrat1, kwadrat2; trojkat1, trojkat2; kolo1, kolo2; *lista[6]; = = = = = = &trojkat1; &kwadrat1; &kolo1; &kwadrat2; &kolo2; &trojkat2; for (int i=0; i<6; i++) lista[i]->rysuj(); } Trojkat Kwadrat Kolo Kwadrat Kolo Trojkat Informatyka 2, studia niestacjonarne I stopnia Rok akademicki 2012/2013, Wykład nr 6 dr inż. Jarosław Forenc 17/17 Koniec wykładu nr 6 Dziękuję za uwagę!