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ę!