Witaj, Gościu O nas | Kontakt | Mapa
Wortal Forum PHPEdia.pl Planeta Kubek IRC Przetestuj się!

Podstawy - Programowanie obiektowe dla początkujacych

Wprowadzenie do programowania obiektowego

Aktualnie rozróżniamy dwa główne trendy programistyczne: programowanie strukturalne (ang. Structural Programming) oraz programowanie zorientowane obiektowo (ang. Object Oriented Programming). Istnieją także inne paradygmaty, jak np. programowanie aspektowe. Poza tym, pewną ewolucją programowania strukturalnego, jest programowanie oparte o moduły. Temat jest bardzo szeroki, ale na razie skupimy się na dwóch pierwszych zagadnieniach.

Do tej pory powstało bardzo wiele aplikacji napisanych zarówno w PHP, jak i z wykorzystaniem innych technologii, które zostały stworzone wyłącznie w oparciu o struktury. Znaczna część tych aplikacji ma wysoki stopień złożoności i zaawansowania. Można więc zadać sobie zasadnicze pytanie: Po co programować obiektowo, skoro ten sam efekt można osiągnąć programując strukturalnie? Otóż programując obiektowo, można osiągnąć ten sam efekt mniejszym nakładem pracy i energii. Ponadto, kod zorientowany obiektowo jest mniejszy objętościowo, niż kod strukturalny, jest lepiej uporządkowany i co za tym idzie, łatwiej nad nim zapanować. W artykule skupimy się na programowaniu w PHP5, ale zostaną też opisane pewne różnice pomiędzy programowaniem obiektowym w PHP4 i PHP5. Niniejszy artykuł zawiera jedynie część podstawowych zagadnień związanych z programowaniem obiektowym. Aby poszerzyć zakres swojej wiedzy, należy sięgnąć do innych, szerszych źródeł informacji. Niektóre z nich są wymienione w dalszej części artykułu.

Klasy i obiekty w PHP

Klasy, obiekty, atrybuty i metody

Klasa określa nowy typ danych. Jest kontenerem przechowującym atrybuty, czyli zmienne klasy oraz metody, czyli funkcje klasy. Między różnymi klasami mogą istnieć zależności, o czym jest mowa w dalszej części artykułu. W Listingu 01 jest zaprezentowana przykładowa klasa.

<?php
class przykladowaKlasa {
    public $zmienna01;
    public metoda01(){
        echo "Moja metoda";
    }
}

Jak widać, pojawiły się słowa kluczowe public. Określają one dostępność elementów klasy. Będzie o nich mowa w dziale Hermetyzacja w dalszej części artykułu.

Stworzyliśmy już naszą klasę. Teraz chcielibyśmy móc skorzystać z jej funkcjonalności. W związku z tym, musimy skorzystać z obiektów. Obiekt jest pojedynczą instancją danej klasy. Możemy tworzyć dowolną ilość instancji naszej klasy. Obiekty tworzymy za pomocą operatora new. Metody z klasy wywołujemy za pomocą operatora ->. W Listingu 02 jest pokazane przykładowe utworzenie obiektu oraz wywołanie jego metody. Należy pamiętać, aby wcześniej zdefiniować odpowiednią klasę. W naszym przykładzie skorzystamy z klasy pochodzącej z Listingu 01.

<?php
$obiekt = new przykladowaKlasa();
$obiekt->metoda01();

Efektem działania powyższego kodu będzie wyświetlenie napisu "Moja metoda".

Konstruktory i destruktory

Czasem zdarza się, że podczas każdorazowego tworzenia obiektu musimy wywołać jakąś funkcję lub instrukcję. Może to mieć miejsce np. w sytuacji, gdy tworzymy klasę do obsługi bazy danych i chcemy zawsze po utworzeniu instancji połączyć się z bazą danych lub gdy np. tworzymy klasę do obsługi logów (dziennika zdarzeń) i chcemy podczas tworzenia obiektu otworzyć plik. W takich sytuacjach z pomocą przychodzą nam konstruktory. Konstruktor jest to metoda, która jest wykonywana za każdym razem, kiedy obiekt zostanie utworzony. Definiujemy go za pomocą słowa kluczowego __construct(). Listing 03 przedstawia przykładowy konstruktor i utworzenie obiektu.

<?php
class przykladowaKlasa {
    public function __construct(){
        echo "Jestem konstruktorem";
    }
}

$obiekt = new przykladowaKlasa();

Dziedziczenie

Jak już zostało wspomniane, między klasami mogą istnieć zależności. Klasy mogą dziedziczyć po sobie metody oraz atrybuty. Aby lepiej zobrazować zagadnienie, posłużę się przykładem zamieszczonym w Listingu 04.

<?php
class Zwierze {
    public $waga;
    public $szybkosc;
    
    public biegnij() {}
    public jedz() {}
    public poluj() {}
}

class Lew extends Zwierze {
    public __construct(){
        $this->waga = 80;
        $this->szybkosc = 150;
    }
    public function rycz(){
        echo 'Lew ryczy.';
    }
    public function poluj(){
        echo 'Lew poluje inaczej, niż wszystkie zwierzęta';
    }
}

class Slon extends Zwierze {
    public __construct(){
        $this->waga = 580;
        $this->szybkosc = 20;
    }
    public function machajTraba(){
        echo 'Słoń macha trabą.';
    }
}

Przeanalizujmy powyższy przykład. W klasie o nazwie Zwierze zostały zdefiniowane konkretne atrybuty oraz metody. Słowo kluczowe extends oznacza po jakiej klasie dziedziczy druga klasa. W tym przykładzie klasy Lew oraz klasa Slon odziedziczyły wszystkie metody i atrybuty z klasy Zwierze. Prostą zależność pomiędzy tymi klasami pokazuje Rys. 01.

Pojawiło się słowo kluczowe $this. Określa ono odwołanie się do wewnętrznych elementów klasy, tj. metod i atrybutów. Atrybuty $waga oraz $szybkosc zostały odziedziczone przez klasy Lew oraz Slon, więc można się do nich odwołać, jak do elementów wewnętrznych klasy i przypisać im wartości. W klasach pochodnych zostały zdefiniowane także dodatkowe metody zwiększające funkcjonalność klas (metoda rycz() oraz machajTraba()). Dodatkowo, w klasie Lew została ponownie zdefiniowana metoda poluj(). Dzięki temu zabiegowi, wspomniana metoda zdefiniowana w klasie nadrzędnej została nadpisana w klasie podrzędnej i jej zachowanie może być inne, niż w przypadku metody z klasy nadrzędnej.

Dostęp do metod z danej klasy możemy uzyskać za również pomocą operatora zasięgu :: (ang. scope operator). Do klasy nadrzędnej możemy się odwołać za pomocą słowa kluczowego parent, natomiast do innych klas możemy się odwoływać używając nazwy klasy. Należy pamiętać, że korzystając z operatora zasięgu poza klasą, nie uzyskujemy dostępu do wewnętrznych atrybutów i metod klasy, ponieważ nie tworzymy obiektu, a jedynie wywołujemy pojedynczą metodę. Przykładowe użycie operatora zasięgu przedstawia Listing 05.

<?php
class Klasa01 {
    public function metoda01 {}
}

class Klasa02 extends Klasa01 {
    public function metoda02(){
        parent::metoda01();
    }
    public function metoda03() {}
}

Klasa02::metoda03();

W PHP nie ma wielodziedziczenia, które jest znane m.in. programującym w języku C++. Każda klasa może dziedziczyć tylko po jednej klasie.

Polimorfizm

Polimorfizm, to inaczej wielopostaciowość. W skrócie oznacza to, że zachowanie metody może się różnić w zależności od użytego obiektu. W Listingu 04. W klasie Zwierze została zawarta metoda poluj(). Natomiast w klasie podrzędnej - Lew ta metoda została nadpisana, w związku z czym, jej zachowanie będzie inne, niż w przypadku klasy Zwierze. W przypadku klasy Slon zachowanie tej metody będzie takie samo, jak w przypadku klasy nadrzędnej. Jak widać, pomimo tego, że dwie klasy wywodzą się z jednej klasy głównej, zachowanie niektórych ich metod może być różne. Ponadto, funkcja z klasy nadrzędnej ma dostęp do atrybutów i metod podklasy, z której ją wywołujemy.

Hermetyzacja

W niektórych sytuacjach chcemy ograniczyć pole działania niektórych metod oraz dostępność atrybutów. Np. możemy zażyczyć sobie, aby klasa pochodna nie miała dostępu do niektórych właściwości klasy lub chcemy wykonywać pewne operacje tylko w obrębie klas. W takich sytuacjach z pomocą przychodzi nam hermetyzacja. Dostępność metod i atrybutów definiujemy za pomocą słów kluczowych public, protected oraz private, które stawiamy przed definicjami wspomnianych elementów. W pierwszej kolejności należy określić właściwości ww. słów kluczowych.

  • public - Dostęp do atrybutu lub metody jest możliwy wewnątrz klasy, w klasach pochodnych oraz poza klasą.
  • protected - Dostęp do atrybutu lub metody jest możliwy tylko wewnątrz klasy i w klasach pochodnych
  • private - Dostęp do atrybutu lub metody jest możliwy tylko wewnątrz klasy.

Przykładowe wykorzystanie hermetyzacji obrazuje Listing 06.

<?php
class Klasa01  {
    public function metoda01(){
        echo "ta  metoda jest dostępna z każdego miejsca";
    }
    protected function metoda02(){
        echo  "ta metoda jest dostępna tylko wewnątrz klasy i w klasach pochodnych";
    }
    private function metoda03(){
        echo  "tej metody można używać tylko wewnątrz klasy";
    }
}

Wzorce projektowe

Z programowaniem obiektowym ściśle wiążą się wzorce projektowe. Nie są one tematem niniejszego artykułu, dlatego zostaną one opisane w bardzo zawężonym zakresie. Wzorce projektowe są to pewne koncepcje i paradygmaty programistyczne pozwalające rozwiązać często spotykane przez programistów problemy. Znając wzorce projektowe, możemy przyspieszyć proces tworzenia oprogramowania, a nasze projekty uczynić bardziej stabilnymi, ponieważ sprawdzone rozwiązania najlepiej pomogą nam poradzić sobie z częstymi problemami.

Jednym z wielu wzorców projektowych jest wzorzec fabryki (Factory). Wzorzec fabryki pozwala na tworzenie instancji klasy w locie. Jest określony jako wzorzec fabryki, ponieważ odpowiada za wytwarzanie obiektu. Przykład jego użycia przedstawia Listing 07. W tym przykładzie wzorzec fabryki odpowiada za ładowanie odpowiedniego sterownika bazy danych.

<?php
class Przyklad {
    public function factory($type){
        if( include_once('Drivers/'.$type .'.php') ){
            $classname = 'Driver_' . $type;
            return new $classname;
        } else {
            return false;
        }
    }
}

// Ładuje sterownik MySQL
$mysql = Przyklad::factory('MySQL');

// Ładuje sterownik PostgreSQL
$pgsql = Przyklad::factory('PostgreSQL');

Ograniczenia PHP4

Niniejszy artykuł odnosi się do programowania w PHP5, a prace nad czwórką już jakiś czas temu zostały zakończone. Niemniej jednak warto znać ograniczenia związane z programowaniem w PHP4, w którym mogliśmy zaobserwować jedynie namiastkę programowania obiektowego.

Niektóre ograniczenia związane z programowaniem w PHP4 są następujące:

  • brak hermetyzacji,
  • brak interfejsów,
  • brak klas abstrakcyjnych,
  • brak automatycznego ładowania klas,
  • brak obsługi wyjątków,
  • i brak wielu innych funkcjonalności, o których można przeczytać na stronie http://pl.php.net/manual/pl/language.oop5.php (EN).

Większość wymienionych elementów nie zostało opisanych w niniejszym artykule, gdyż dotyczy on jedynie podstaw programowania obiektowego, ale znacznie poszerzają one pole manewru programisty, dlatego warto się z nimi zapoznać.

Obecnie PHP4 odchodzi do lamusa, ale warto mieć o nim jakiekolwiek pojęcie, gdyż sporo aplikacji napisanych w tej wersji języka funkcjonuje jeszcze w Internecie i warto wiedzieć, że nie ma sensu ich rozwijać wg starej konwencji. Najlepiej jest je przepisać lub zaprojektować od nowa wg standardów wytyczanych przez PHP5, jeśli chce się o nich myśleć przyszłościowo.

Podsumowanie

Reasumując, do tworzenia prostych aplikacji, wykonujących pojedynczą czynność programowanie strukturalne w zupełności wystarczy. Natomiast jeżeli chcemy zajmować się tworzeniem rozbudowanych serwisów lub systemów, programowanie obiektowe jest elementem niezbędnym. Obecnie, każda poważna, złożona aplikacja jest zaprojektowana obiektowo, a sama idea programowania dotyczy nie tylko PHP, ale także wielu innych języków programowania. Wszystkie wzorce projektowe i frameworki są tworzone z wykorzystaniem obiektów. Umożliwia to łatwe panowanie nad projektem i zapewnia jego skalowalność. Warto zapoznać się z opisem programowania obiektowego zawartym w podręczniku (manualu) w serwisie php.net: http://pl.php.net/manual/pl/language.oop5.php (EN).

Mając umiejętność biegłego poruszania się po obiektowym kodzie, będziemy mogli uczynić własną pracę i naukę szybszą, prostszą, wygodniejszą i bardziej profesjonalną.

Wasze opinie
Wszystkie opinie użytkowników: (0)
Mentax.pl    NQ.pl- serwery z dodatkiem świętego spokoju...   
O nas | Kontakt | Mapa serwisu
Copyright (c) 2003-2024 php.pl    Wszystkie prawa zastrzeżone    Powered by eZ publish Content Management System eZ publish Content Management System