<?
metoda_czy_funkcja(NAZWA $zmienna){
}
?>
W PHP taka konstrukcja oznacza, że parametr $zmienna musi:
1) Obiektem klasy NAZWA
2) Obiektem, któego klasa dziedziczy po NAZWA
3) Obiektem, którego klasa implementuje interfejs NAZWA
(dodatkowo takie wymusznie typu możesz zostosować jeszcze do tablic (array). I niestety tylko tyle)
Co do interefejsów:
Wyobraź sobie, że masz obok siebie cztery telewizory. Każdy z nich ma pięć przycisków:
1) Power (off/on)
2) Zwiększ głośność
3) Zmniejsz głośność
4) Kanał w górę
5) Kanał w dół
Gdy chcesz włączyć którykolwiek z tych telewizorów wykonujesz następującą akację:
wciskasz przycisk power. I z Twojej strony to już jest koniec operacji. Teraz wewnątrz telewizora jego elektornika włącza wyświetlacz (zwróć uwagę, że Ciebie to już nie interesuje czy to jest kineskop, ekran LCD czy plazma), głośniki (ponownie nie interesuje Cie czy to jest jeden głośnik mono czy stereo czy może telewizor korzysta z zewnętrznego układu głośników) itp.
Jeszcze jeden przykład: Jakiego byś telewizoru nie kupił będziesz potrafił korzystać z jego podstawowych opcji na pilocie (5 punktów powyżej). Dlaczego? Ponieważ jest tam powtórzony pewien schemat,
jednolity interfejs. Oczywiście pilot może oferować dużo większe możliwości (takie, których inne nie oferują) ale te, które są zapisane w interfejscie wykonuje dokładnie tak samo jak inne piloty.
A więc interfejs ujednolica dostęp do określonych zachowań (w OOP można by przyjąć, że w polach przechowujemy stany obiektu (np. telewizor: włączony/wyłączony, glośność 80, 70, 100, kontrast: 75, 22) a w metodach mamy "zachowania" (zmiejsz/zwiększ kontrast, włącz/wyłącz))
Co do klas/metod abstrakcyjnych. One pozwalają na to by pewne zachowania były wspólne dla różnych obiektów. Dzięki temu, że raz zapiszemy pewne zachowanie w klasie abstrakcyjnej (którą dziedziczy klasa dziecko) nie musimy pisać tego samego kodu 5 razy. Ponownie przykład telewizorów:
<?
interface iTelewizor{
public function wlacz();
public function glosnosc($wartosc = 0);
public function kontrast($wartosc = 100);
}
abstract class Telewizor{
protected $wlaczony = false;
protected $glosnosc = 75;
protected $mute = false;
protected $kontrast = 40;
//wszystkie telewizory dzialaja tak samo. Jak jest wlaczony i klikniemy "Power" to sie wylaczy i vice versa
public function wlacz(){
$this->wlaczony = ($this->wlaczony === false) ? true : false;
}
protected function mute(){
return $this->mute = ($this->mute === false) ? true : false;
}
}
class Kineskopowy extends Telewizor implements iTelewizor{
//nasz kineskopowy telewizor w przypadku gdy glosnosc jest rowna zeru wlacza funkc
je mute.
public function glosnosc($wartosc = 0){
if($wartosc == 0)
return $this->mute();
$this->glosnosc = (int) $wartosc;
}
//reszta klasy bez metody wlacz();
}
class LCD extends Telewizor implements iTelewizor{
//natomiast nasz nowy LCD, dbajac o nasze zdrowie w przypadku proby ustawienia zby
t duzej glosnosci poprosi jeszcze o potwierdzenie
//przy $wartosc = 0, nie wlacza mute, poprostu scisza do zera
public function glosnosc($wartosc = 0){
if($wartosc >= 75){
$this->potwierdzenieGlosnosci();
}
$this->glosnosc = (int) $wartosc;
if($this->posiadamZewnetrzySystemGlosnikow()){
$this->glosnoscSubbuffera = $this->zmiejszGlosnoscSubbufera($wartosc); //w osobnej metodzie, ktora ma jakis tam algorytm okreslajacy o ile zmiejszyc (normalnie powinno okreslac czy zmiejszyc czy wiekszyc w zaleznosci od tego
co robimy) glosnosc glosnika niskotonowego
}
}
//reszta klasy bez metody wlacz();
}
?>
Klasy abstrakcyjne pozwalają nam (programiście, nie uzytkownikowi (warto zaznaczyć, że programista jest czasami użytkownikiem)) zaimplementować pewne powatarzale zachowania.