Podstawy programowania II 3


Podstawy programowania II
dr inż. Paweł Róg
1
Zagadnienia
%
Zagadnienia zaawansowane
ą
Pola stałe.
ą
Polimorfizm.
ą
Klasy i metody abstrakcyjne.
ą
Interfejsy.
ą
Klasy i metody finalne.
ą
Informacja o typie w czasie wykonania.
ą
Magiczne metody.
2
Pola stałe
%
Pola stałe definiujemy za pomocą słowa const.
class Produkt {
protected $typ;
protected $nazwa;
const FUNTY_NA_KG = 0.45359237;
// ...
}
3
Pola stałe
%
Odwołanie do stałej z wnętrza klasy:
self::FUNTY_NA_KG;
%
Odwołanie do stałej z zewnątrz:
Produkt::FUNTY_NA_KG;
4
Pola stałe
%
Wartości stałego pola nie można zmienić, można
jednak nadpisać takie pole w klasie pochodnej:
class klasaA {
const STALA_LICZBA=5;
}
class klasaB extends klasaA {
const STALA_LICZBA=21;
}
print klasaA::STALA_LICZBA . '
';
print klasaB::STALA_LICZBA ;
5
Polimorfizm
Polimorfizm (wielopostaciowość) jest mechanizmem
Polimorfizm (wielopostaciowość) jest mechanizmem
programowania obiektowego polegającym na
programowania obiektowego polegającym na
dynamicznym
dynamicznym określaniu zachowania obiektu w trakcie
określaniu zachowania obiektu w trakcie
działania
działania programu na podstawie jego rzeczywistego
programu na podstawie jego rzeczywistego
typu.
typu.
%
Jako przykład rozpatrzmy hierarchię klas implementującą
proste obiekty  graficzne .
%
Klasą bazową dla wszystkich obiektów będzie klasa
Figura.
%
Najważniejszą metodą w tej hierarchii klas będzie metoda
rysuj()  wyświetlająca figurę na ekranie.
%
Pozostałe klasy (Kwadrat, Trojkat, Kolo) będą
dziedziczyć po klasie Figura i dostarczać własną
implementację metody rysuj().
6
class Figura {
public function rysuj() {
print "Rysuję bezkształtną
figurę...
";
}
}
class Kwadrat extends Figura {
public function rysuj() {
print "Rysuję kwadrat!
";
}
}
7
class Trojkat extends Figura {
public function rysuj() {
print "Rysuję trójkąt!
";
}
}
class Kolo extends Figura {
public function rysuj() {
print "Rysuję koło!
";
}
}
8
funkcja rysowanie(Figura $f) {
print "Inne operacje...
";
$f->rysuj();
}
for (int $i=0; $i<10; $i++) {
$losowa = rand(1,3);
switch ($losowa) {
case 1 : $figury[$i] = new Kwadrat(); break;
case 2 : $figury[$i] = new Trojkat(); break;
default: $figury[$i] = new Kolo();
}
foreach ($figury as $f) {
rysowanie($f);
}
9
Klasy abstrakcyjne
%
W poprzednim przykładzie widać bardzo wyraznie, że nie
ma sensu tworzyć obiektu klasy Figura, gdyż wywołanie
dla niego metody rysuj() nie ma większego sensu.
Z drugiej strony, klasa Figura nadaje się bardzo dobrze
na klasę bazową dla innych, konkretnych klas figur. Fakt
ten możemy wyrazić, czyniąc klasę Figura klasą
abstrakcyjną:
abstract class Figura {
public function rysuj() {
print "Rysuję bezkształtną
figurę...
";
}
}
0
1
Metody abstrakcyjne
%
Abstrakcyjna klasa Figura nie dostarcza
sensownej implementacji dla metody rysuj()
i dlatego naturalne będzie określenie, że metoda
ta jest abstrakcyjna. W ten sposób dajemy do
zrozumienia, że sensowna implementacja tej
metody dostarczona zostanie przez klasy
pochodne:
abstract class Figura {
abstract public function rysuj();
}
}
1
1
Interfejsy
%
Możemy iść jeszcze dalej i zastrzec, że Figura
deklaruje jedynie interfejs, który musi być
zaimplementowany przez konkretne klasy figur:
interface Figura {
public function rysuj();
}
}
class Kwadrat implements Figura {
public function rysuj() {
print "Rysuję kwadrat!
";
}
}
2
1
Klasy finalne
%
Jeśli chcemy, aby z danej klasy nie można było
wyprowadzać klas potomnych, należy definicję
klasy poprzedzić modyfikatorem final:
final class Kwadrat implements Figura {
public function rysuj() {
print "Rysuję kwadrat!
";
}
}
3
1
Metody finalne
%
Jeśli chcemy, aby dana metoda nie mogła zostać
nadpisana w klasie pochodnej, należy definicję tej
metody poprzedzić modyfikatorem final:
class Kwadrat implements Figura {
final public function rysuj() {
print "Rysuję kwadrat!
";
}
}
4
1
Powtórzenie
%
Aby zadeklarować pole stałe w klasie należy użyć
modyfikatora const.
%
Wartość stałego pola nie może być zmieniona
w czasie wykonania programu, można jednak
nadpisać stałe pole w klasie pochodnej.
%
Polimorfizm (wielopostaciowość) jest
mechanizmem programowania obiektowego
polegającym na dynamicznym określaniu
zachowania obiektu w trakcie działania programu
na podstawie jego rzeczywistego typu.
%
Jeśli chcemy, aby klasa mogła być klasą
pochodną dla innych klas, ale nie ma sensu
tworzyć obiektów tej klasy, powinna być ona klasą
abstrakcyjną (abstract).
5
1
Powtórzenie
%
Jeśli jakaś klasa jest na tyle wysoko w hierarchii
klas, że nie wszystkie jej metody mogą być
sensownie zaimplementowane, metody te należy
uczynić abstrakcyjnymi.
%
Interfejs (interface) deklaruje, co może być
zrobione, ale nie mówi jak. Dopiero klasa, która
implementuje (implements) interfejs dostarcza
konkretnych implementacji metod.
%
Jeśli z jakichś względów nie chcemy, aby dana
klasa mogła być klasą bazową dla innych klas,
musimy zadeklarować ja jako final.
%
Jeśli nie chcemy, aby jakaś metoda mogła być
nadpisana w klasach pochodnych, również
musimy uczynić ją final.
6
1
Informacja o typie w czasie wykonania
%
get_class()
%
get_parent_class()
%
is_subclass_of()
%
instanceof
7
1
get_class()
%
Aby w trakcie działania programu otrzymać typ
danego obiektu możemy wykorzystać funkcję
get_class():
$figura = new Kwadrat();
print get_class($figura);
8
1
get_parent_class()
%
Aby w trakcie działania programu otrzymać typ
klasy bazowej dla danego obiektu możemy
wykorzystać funkcję get_parent_class():
$kwadrat = new Kwadrat();
print get_parent_class($kwadrat);
9
1
is_subclass_of
%
Aby sprawdzić, czy dany obiekt jest obiektem
klasy, która jest klasą pochodną wobec innej
klasy, możemy użyć funkcji is_subcalss_of():
$kwadrat = new Kwadrat();
if (is_subclass_of($kwadrat, 'Figura'))
{
print 'OK';
}
0
2
instanceof
%
Podobne działanie do funkcji
is_subclass_of() ma operator instanceof,
z tą różnicą, że instanceof pozwala sprawdzić
również, czy dany obiekt implementuje dany
interfejs:
$kwadrat = new Kwadrat();
if ($kwadrat instanceof Figura) {
print 'OK';
}
1
2
Zastosowanie instanceof
function rysowanie ($cos) {
if ($cos instanceof Figura) {
$cos->rysuj();
} else {
print 'Tego czegoś nie da się
narysować...';
}
2
2
Magiczne metody
%
__toString()
%
__get()
%
__set()
3
2
__toString()
%
Magiczna metoda __toString() umożliwia
automatyczne otrzymanie tekstowej reprezentacji
obiektu:
class Kwadrat extends Figura {
// ...
public function __toString() {
return 'KWADRAT';
}
}
$kwadrat = new Kwadrat();
print $kwadrat;
4
2
__get() i __set()
class Leniwa {
protected $_props;
public function __get($nazwa) {
if (isset($this->_props[$nazwa]){
return $this->_props[$nazwa];
} else {
return false;
}
}
public function __set($nazwa, $wartosc) {
$this->_props[$nazwa] = $wartosc;
}
}
5
2


Wyszukiwarka