Programowanie obiektowe w PHP5 - drugie starcie - dziedziczenie i interfejsy

Jedną z głównych zalet stosowania programowania obiektowego jest, to że uzyskujemy możliwość podzielenia kodu na niezależne częścim które później można ponownie wykorzystać. Takich ówcześnie przygotowanych części kodu można używac wielokrotnie w różnych projektach.

W poprzednim artykule pisaliśmy klasę Zwierzak, wyobraźmy sobie, że teraz poprzebujemy dodatkowo kilka zwierząt, trochę bliżej opisanych, ze wspólnymi cechami. Nie bedziemy przecież kopiować tej klasy w nieskończoność dorabiając właściwości czy metody. Wprowadzi to nam sporo bałaganu z kod oraz może powodować olbrzymie problemy w przypadku, gdy popełniliśmy błąd w klasie Zwierzak, ponieważ będziemy musieli poprawiać ją w każdym miejscu gdzie skopiowolaliśmy kod klasy. pierwszą z metod, która nam może pomóc jest dziedziczenie (ang. inheritance).

Dziedziczenie

Załóżmy, że wszystkie nasze zwierzaki będa miały cechy wspólne, takie jak kolor, wydawany dźwięk, ilość łap, nazwa, rodzaj, gatunek etc... Właściwości opisujące te cechy możemy dopisac do każdej klasy zwierzęcia, ale można też wykorzystać słowo kluczowe extends i mechanizm dziedziczenia, aby zdefiniować te właściwości w jednej klasie współdzielonej przez wszystkie. W tym celu powinniśmy przygotować klasę Zwierzak, która posłuży nam jako szkielet do tworzenia innych klas zwierząt. Każda z tych klas, niezależnie jakie zwierze będzie opisywać, zawierać będzie w sobie podstawowe funckje klasy Zwierzak. Najprostszym sposobem opisania tego stosunku jest dziecko-rodzic. Klasa Zwierzak jako rodzic dla klasy dziecka np. Pies, stąd też ta zalezność nazywa się dziedziczeniem i aby ją opisać używamy angielsiego słówka extends.

<?php
class Zwierzak
{
   public 
$kolor='czarny';
   public 
$nazwa='jakiś zwierz';
}

class 
Pies extends Zwierzak
{
   public 
$nazwa='pies';
   public 
$dzwiek='hau, hau';
   public 
$imie='Burek';
}

$c=new Pies();
echo 
"Nasz $c->nazwa ma na imię $c->imie! Jest $c->kolor i wydaje $c->dzwiek!";?>

Po uruchomieniu tego kodu zobaczymy:

Nasz pies ma na imię Burek! Jest czarny i wydaje hau, hau!

Jak widać, przygotowaliśmy klasę bazową o nazwie Zwierzak w której wczesnie zdefiniowaliśmy podstawową właściwość $kolor. Dzięki użyciu słowa extends do naszej klasy pies zostały dołączone wszystkie właściwości i metody klasy Zwierzak. Klasa Pies jest wywiedziona z klasy Zwierzak, dlatego mamy z niej właściwość $kolor, mimo że nie jest ona jawnie napisana w klasie Zwierzak. Jak już zapewne zauważyliśmy w przykładzie również przedefiniowaliśmy właściwość $nazwa. Zmieniając w klasie wywiedzionej definicję właściwości $nazwa, ukrywamy definicję tej właściwości dziedziczoną po klasie bazowej. W ten sam sposób zachowują się metody.

Słowo kluczowe final

Jeżeli chcielibyśmy zabronić klasom potomnym modyfikowania metod klasy bazowej, musimy użyć słowa kluczowego final przed definicją elementu.

<?php
class Zwierzak
{
   public 
$kolor='czarny';
   public 
$nazwa='jakiś zwierz';

   final public function 
getkolor()
   {
      return 
$this->kolor;
   }
}

class 
Pies extends Zwierzak
{
   public 
$nazwa='pies';
   public 
$dzwiek='hau, hau';
   public 
$imie='Burek';

   public function 
getkolor()
   {
      return 
'to się nie uda';
   }
}

$c=new Pies();
echo 
"Nasz $c->nazwa ma na imię $c->imie! Jest $c->kolor i wydaje $c->dzwiek!";?>

W wyniku próby uruchomienia powyższego kodu uzyskamy:

Fatal error: Cannot override final method Zwierzak::getkolor() in /home/blog/test/pies.php on line 23

Stosowanie referecji parent

Czasami zachodzi potrzeba odwołania się do elementu rodzica w tym celu musimy posłużyć się słowem kluczowym parent.

<?php
class Rodzic
{
   public function 
imie()
   {
      return 
'Bożena';
   }
}

class 
Dziecko extends Rodzic
{
   public function 
imie()
   {
      return 
'Agnieszka';
   }

   public function 
rodzina()
   {
      return 
'Dziecko '.$this->imie().' ma rodzica o imieniu '.parent::imie();
   }
}

$c=new Dziecko();

echo 
$c->rodzina();
?>

Wynikiem działania kodu będzie:

Dziecko Agnieszka ma rodzica o imieniu Bożena

Klasy abstrakcyjne

Wracająć do naszego przykładu klasy Zwierzak. Jeżeli chcemy aby ów klasa nie funkcjonowała w kodzie jako samodzielny obiekt musimy ją zadeklarować jako abstarkcyjną, czyli użyć słówa kluczowego abstract przed definicją klasy.

<?php
abstract class Zwierzak
{
   public 
$kolor='czarny';
   public 
$nazwa='jakiś zwierz';
}

class 
Pies extends Zwierzak
{
   public 
$nazwa='pies';
   public 
$dzwiek='hau, hau';
   public 
$imie='Burek';
}

$c=new Pies();
echo 
"Nasz $c->nazwa ma na imię $c->imie! Jest $c->kolor i wydaje $c->dzwiek!";

$zw=new Zwierzak();
echo 
$zw->kolor;
?>

po uruchomienu tego kodu powinniśmy uzyskać podobny rezultat:

Nasz pies ma na imię Burek! Jest czarny i wydaje hau, hau!
Fatal error: Cannot instantiate abstract class Zwierzak in /home/blog/test/pies.php on line 18

Interfejsy

Kolejną funkcją języka PHP5 zwiążąną z nowym modelem obiektów jest możliwość tworzenia i wykorzystywania interfejsów. Mówiąc w skrócie, interfejsy są pewnym sposobem na okreslenie metod, jakie ma implementować dana klasa. Przydaje się one w sytuacjach, w których pracuje wiele ze sobą połączonych obiektów, które wywołują między sobą ściśle określone metody. Dzięki nim, jeżeli kiedykolwiek będziemy zmuszeni do zmiany klasy wykorzystywanej w naszej aplikacji, musimy się tylko upewnić, że nowa klasa implementuje ten sam interfejs co klasa pierwotna. Rozpatrzmy to na przykładzie:

<?php
interface Zwierzak
{
   public function 
setkolor($nowykolor);
   public function 
getkolor();
}

class 
Pies implements Zwierzak
{
   private 
$kolor='czarny';

   public function 
setkolor($nowykolor)
   {
      
$this->kolor=$nowykolor;
   }

   public function 
getkolor()
   {
      return 
$this->kolor;
   }
}

$c = new Pies();
$c->setkolor('czerwony');
echo 
$c->getkolor();
?>

Usunięcie, którejkolwiek z metod klasy Pies spowoduje wyświetlenie krytycznego błędu, że nie zdefiniowano niezbędnej metody.

Your rating: Brak Ocena: 4 (6 votes)

opisany pies

kocham p:) :)

Dodaj nową odpowiedź

Zawartość pola nie będzie udostępniana publicznie.
  • Adresy internetowe są automatycznie zamieniane w odnośniki, które można kliknąć.
  • Dozwolone znaczniki HTML: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Znaki końca linii i akapitu dodawane są automatycznie.
  • You can use the <go> tags just like the <a> for nicer urls.

Więcej informacji na temat formatowania