Programowanie obiektowe

16
Programowanie obiektowe Wykład dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/16 Programowanie obiektowe Wykład 4 cz. I Dziedziczenie (C++) Dariusz Wardowski

description

Programowanie obiektowe. Wykład. Programowanie obiektowe Wykład 4 cz. I Dziedziczenie (C++). Dariusz Wardowski. d r Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ. Programowanie obiektowe. Wykład. Dziedziczenie. Co to jest dziedziczenie? - PowerPoint PPT Presentation

Transcript of Programowanie obiektowe

Page 1: Programowanie obiektowe

Programowanie obiektowe Wykład

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/16

Programowanie obiektoweWykład 4 cz. I

Dziedziczenie (C++)

Dariusz Wardowski

Page 2: Programowanie obiektowe

Programowanie obiektowe Wykład

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 2/16

Dziedziczenie

Zalety dziedziczenia:

Możliwość tworzenia kodu, który da się wielokrotnie wykorzystać.Lepiej jest stosować kod już sprawdzony, niż wymyślać rozwiązanie od podstaw.Korzystanie z istniejącego kodu nie tylko skraca czas programowania, lecz również pozwala uniknąć błędów.Im mniej koncentrujemy się na szczegółach tym bardziej zrozumiały i przejrzysty jest cały projekt.

Wzbogacanie istniejących klas o dodatkową funkcjonalność oraz deklarowanie w nowych klasach dodatkowych danych.Modyfikowanie działań metod już istniejących bez modyfikacji starego kodu.

Co to jest dziedziczenie?

Jest to mechanizm umożliwiający tworzenie nowych klas na podstawie klasy już istniejących w ten sposób, że nowa klasa przejmuje (dziedziczy) wszystkie metody drugiej klasy .

Page 3: Programowanie obiektowe

Programowanie obiektowe Wykład

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 3/16

Klasa macierzysta

Klasa oryginalna, na podstawie której tworzymy nową, nazywamy klasą macierzystą.

Deklaracja klasy macierzystej (Pracownik.h)

class Pracownik{ private:

enum [ILE = 20];char imie[ILE];char nazwisko[ILE];char stanowisko[ILE];double pensja;

public:Pracownik(const char* i = „???”, const char* n = „???”, char* s = „???”, double p = 0);void wypiszDane() const;void ustawPensja(double);double getPensja() const;

};

Page 4: Programowanie obiektowe

Programowanie obiektowe Wykład

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 4/16

Definicja klasy macierzystej

Definicja klasy macierzystej (Pracownik.cc)

Pracownik::Pracownik Pracownik(const char* i = „???”, const char* n = „???”, char* s = „???”, double p = 0){ strncpy(imie, i, ILE - 1); strncpy(nazwisko, n, ILE - 1); strncpy(stanowisko, s, ILE - 1); pensja = p;}

void Pracownik::wypiszDane() const{ cout << imie << „ ” << nazwisko << „ ” << stanowisko << „ ” << pensja << endl; }

void Pracownik::ustawPensja(double p){ pensja = p;}

double Pracownik::getPensja() const{ return pensja;}

Page 5: Programowanie obiektowe

Programowanie obiektowe Wykład

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 5/16

Klasa potomna

class Dyrektor : public Pracownik{ private: double dodatekFunkcyjny; public: Dyrektor(double dF = 0, const char* i = „”, const char* n = „”, const char*

stanowisko = „Dyrektor”, double p = 0); Dyrektor(double dF = 0, const Pracownik & p); double getDodatekFunkcyjny() {return dodatekFunkcyjny;} void setDodatekFunkcyjny(double dF) {dodatekFunkcyjny = dF;}};

Klasa, która dziedziczy funkcjonalność innej klasy nazywamy klasą potomną.

Dwukropek oznacza, że klasa Dyrektor powstała z klasy Pracownik, która tutaj stanowi publiczną klasę macierzystą (dziedziczenie publiczne).Obiekt klasy potomnej zawiera wszystkie pola składowe i metody klasy macierzystej.Gdy dziedziczenie jest publiczne, to wszystkie składowe publiczne klasy macierzystej stają się składowymi publicznymi klasy potomnej. Dostęp do odziedziczonych prywatnych składowych jest możliwy poprzez odziedziczone publiczne lub chronione metody klasy macierzystej.

Page 6: Programowanie obiektowe

Programowanie obiektowe Wykład

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 6/16

Obiekt klasy potomnej

Obiekt klasy Dyrektor ma następujące cechy:• Zawiera w sobie poza swoimi polami, pola klasy macierzystej, czyli: imie, nazwisko, stanowisko, pensja, dodatekFunkcyjny.

• Może korzystać z metod klasy macierzystej: wypiszDane(), ustawPensja(), getPensja().

• Składowe prywatne imie, nazwisko, stanowisko, pensja są dziedziczone, lecz nie są bezpośrednio dostępne.

• Wartość składowej pensja jest dostępna jedynie poprzez odziedziczoną metodę publiczną getPensja().

W klasie potomnej powinna być zdefiniowane własne konstruktory, które dostarczają danych zarówno dla nowych pól jak i odziedziczonych.Klasa potomna może być uzupełniona o dodatkowe pola składowe i metody.

Page 7: Programowanie obiektowe

Programowanie obiektowe Wykład

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 7/16

Konstruktory klasy potomnej

Klasa potomna nie może korzystać z prywatnych składowych klasy macierzystej, musi więc odwoływać się do nich za pomocą publicznego interfejsu klasy macierzystej. W konsekwencji konstruktory klasy potomnej mogą wykorzystywać konstruktory klasy macierzystej.

Podczas tworzenia obiektu klasy potomnej tworzony jest najpierw obiekt klasy macierzystej. Aby wywołać odpowiedni konstruktor klasy macierzystej, wykorzystuje się tzw. listę inicjatorów konstruktora (listę inicjalizacyjną).

Dyrektor::Dyrektor(double dF = 0, const char* i = „”, const char* n = „”, const char* s = „Dyrektor”, double p = 0) : Pracownik(i, n, s, p){ dodatekFunkcyjny = dF;}

Page 8: Programowanie obiektowe

Programowanie obiektowe Wykład

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 8/16

Konstruktor bez listy inicjalizacyjnej

Dyrektor::Dyrektor(double dF = 0, const char* i = „”, const char* n = „”, const char* s = „Dyrektor”, double p = 0){ dodatekFunkcyjny = dF;}

Również w takim przypadku obiekt klasy macierzystej zostanie utworzony jako pierwszy. Pominięcie w tym przypadku listy inicjatorów konstruktora spowoduje uruchomienie konstruktora domyślnego klasy macierzystej. Powyższy konstruktor jest równoważny następującemu:

Dyrektor::Dyrektor(double dF = 0, const char* i = „”, const char* n = „”, const char* s = „Dyrektor”, double p = 0) : Pracownik(){ dodatekFunkcyjny = dF;}

Page 9: Programowanie obiektowe

Programowanie obiektowe Wykład

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 9/16

Konstruktory c.d.

Dyrektor::Dyrektor(double dF = 0, const Pracownik & p) : Pracownik(p)

{ dodatekFunkcyjny = dF;}

Powyższy konstruktor spowoduje wywołanie konstruktora kopiującego klasy macierzystej. W klasie macierzystej nie ma zdefiniowanego jawnie konstruktora domyślnego więc zostanie wywołana jego domyślna wersja.

Przykłady użycia zdefiniowanych konstruktorów:

Dyrektor d1(400, „Jan”, „Kowalski”, „dyrektor”, 3600);

Pracownik p(„Anna”, „Lis”, „dyrektor”, 4000);Dyrektor d2(400, p);

Page 10: Programowanie obiektowe

Programowanie obiektowe Wykład

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 10/16

Lista inicjatorów konstruktora c.d.

Za pomocą listy inicjatorów konstruktora możemy również nadawać wartości polom składowym w klasie potomnej.

Dyrektor::Dyrektor(double dF = 0, const Pracownik & p) : Pracownik(p), dodatekFunkcyjny(dF)

{}

Page 11: Programowanie obiektowe

Programowanie obiektowe Wykład

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 11/16

Podsumowanie o konstruktorach

Gdy tworzony jest obiekt klasy potomnej, jako pierwszy konstruowany jest obiekt klasy macierzystej, który jest częścią klasy potomnej. Zatem pierwszy jest wywoływany konstruktor klasy macierzystej, a dopiero po nim konstruktor klasy potomnej.Konstruktor klasy potomnej powinien przekazywać informacje dotyczące klasy macierzystej do konstruktora tej klasy, posługując się w tym celu listą inicjalizacyjną.Konstruktor klasy potomnej powinien inicjalizować te pola składowe, które zostały dodane do klasy potomnej.Chcąc jawnie wskazać konstruktor klasy macierzystej, który zostanie wywołany w chwili tworzenia obiektu klasy potomnej, należy posłużyć się listą inicjatorów konstruktora. W przypadku, gdy lista ta zostanie pominięta, kompilator użyje konstruktora domyślnego klasy macierzystej.Klasa potomna może przekazywać wartości w górę drzewa dziedziczenia, wyłącznie do klas, po których klasa dziedziczy w sposób bezpośredni.

Page 12: Programowanie obiektowe

Programowanie obiektowe Wykład

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 12/16

Destruktory

Podczas likwidacji obiektu klasy potomnej w pierwszej kolejności wywoływany jest destruktor tej klasy, a następnie wywoływany jest destruktor klasy macierzystej.

Page 13: Programowanie obiektowe

Programowanie obiektowe Wykład

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 13/16

Deklaracja klasy potomnej// pracownikdyrektor.h#ifndef PRACOWNIKDYREKTOR_H_#define PRACOWNIKDYREKTOR_H_class Pracownik{ private:

enum [ILE = 20];char imie[ILE];char nazwisko[ILE];char stanowisko[ILE];double pensja;

public:Pracownik(const char* i = „???”,

const char* n = „???”, char* s = „???”, double p = 0);void wypiszDane() const;void ustawPensja(double p) {pensja = p;};double getPensja() const {return pensja;}

};

class Dyrektor : public Pracownik{ private: double dodatekFunkcyjny; public: Dyrektor(double dF = 0, const char* i = „”, const char* n = „”, const char* stanowisko = „Dyrektor”, double p = 0); Dyrektor(double dF = 0, const Pracownik & p); double getDodatekFunkcyjny() {return dodatekFunkcyjny;} void setDodatekFunkcyjny(double dF) {dodatekFunkcyjny = dF;}};

#endif

Page 14: Programowanie obiektowe

Programowanie obiektowe Wykład

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 14/16

Definicja klasy potomnej// pracownikdyrektor.cc#include „pracownikdyrektor.h”#include <iostream>using namespace std;

Pracownik::Pracownik Pracownik(const char* i = „???”, const char* n = „???”, char* s = „???”, double p=0){ strncpy(imie, i, ILE - 1); strncpy(nazwisko, n, ILE - 1); strncpy(stanowisko, s, ILE - 1); pensja = p;}

void Pracownik::wypiszDane() const{ cout << imie << „ ” << nazwisko << „ ” << stanowisko << „ ” << pensja << endl; }

Dyrektor::Dyrektor(double dF = 0, const char* i = „”, const char* n = „”, const char* s = „Dyrektor”, double p = 0) : Pracownik(i, n, s, p){ dodatekFunkcyjny = dF;}

Dyrektor::Dyrektor(double dF = 0, const Pracownik & p) : Pracownik(p){ dodatekFunkcyjny = dF;}

Page 15: Programowanie obiektowe

Programowanie obiektowe Wykład

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 15/16

Wykorzystanie klasy potomnej

// testpracownikdyrektor.cc#include <iostream>#include „pracownikdyrektor.h”

using namespace std;

int main(){ Pracownik jan(„Jan”, „Kowalski”, „stażysta”, 1500); jan.wypiszDane();

Dyrektor anna(500, „Anna”, „Lis”, „dyrektor”, 3000); anna.wypiszDane();

Dyrektor Jan(500,jan);

return 0;}

Page 16: Programowanie obiektowe

Programowanie obiektowe Wykład

dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 16/16

KONIEC

Dziękuję za uwagę