Programowanie obiektowe w PHP

Transkrypt

Programowanie obiektowe w PHP
PHP 5 – język obiektowy
Wprowadzenie
Klasa w PHP jest traktowana jak zbiór, rodzaj różnych typów danych. Stanowi przepis jak
stworzyć konkretne obiekty (instancje klasy), jest definicją obiektów. Klasa reprezentuje problem
w postaci obiektu, który agreguje wszystkie czynności i stany z nią powiązane. Aby w PHP utworzyć
klasę należy posłużyć się słowem kluczowym class, po którym podaje się jej nazwę. Ciało klasy
umieszcza się wewnątrz nawiasów klamrowych, ciałem klasy są właściwości oraz metody. Metody są
to funkcje, a właściwości to zmienne. Przykładowa klasa np. class Person może zawierać metody
takie jak: setName(), getName(), itp. i może zawierać właściwości takie jak: name, surname,
age, itp..
Metoda różni się od zwykłej funkcji wyłącznie tym, że można ją wywoływać tylko w kontekście
klasy do której należy, to samo dotyczy właściwości. Każda metoda i właściwość posiadają
modyfikator dostępu, który decyduje o ich dostępności na zewnątrz klasy. Modyfikator dostępu
podaje się na samym początku definicji metody lub właściwości. Dostępne modyfikatory to:



public - metoda lub właściwość dostępna jest wewnątrz oraz na zewnątrz klasy,
private - metoda lub właściwość dostępna jest wyłącznie wewnątrz klasy,
protected - metoda lub właściwość dostępna jest wewnątrz klasy głównej oraz wewnątrz
klasy potomnej.
Poniżej przykład prostej klasy:
class Person
{
public $name;
public $surname;
public function setName($name, $surname)
{
$this->name = $name;
$this->surname = $surname;
}
public function getName()
{
return $this->name.' '.$this->surname;
}
}
Utworzenie nowych obiektów klasy Person:
$pawel = new Person();
$ola = new Person();
// Ustawienie właściwości name i surname
$pawel->name = 'Pawel';
$pawel->surname = 'Kowalski';
$ola->name = 'Ola';
1
$ola->surname = 'Widera';
Wyświetlenie wyniku metody getName()
echo $pawel->getName().'<br />';
echo $ola->getName().'<br />';
Wewnątrz klasy do metod i właściwości należy się odnosić poprzez słowo kluczowe this:
$this->propertyName = 'value';
$this->methodName('value');
Po utworzeniu nowego obiektu klasy automatycznie jest uruchamiany konstruktor. Jest to
metoda (magiczna – nie jest jawnie wywoływana, lecz automatycznie) o niezmiennej nazwie
__construct. Jeśli w ciele danej klasy nie będzie umieszczonego konstruktora to mimo wszystko
i tak zostanie uruchomiony domyślny pusty konstruktor, który nic nie będzie robił. Konstruktor jak
każda metoda klasy może posiadać parametry, nie może natomiast zwracać żadnej wartości.
Poniżej znajduje się zmodyfikowana klasa Person, wszystkie jej właściwości zostały ukryte za
pomocą modyfikatora dostępu private, pojawił się natomiast konstruktor wraz z parametrami.
class Person
{
public $name;
public $surname;
public function __construct($name, $surname)
{
$this->name = $name;
$this->surname = $surname;
}
…
}
Tworzenie nowych obiektów klasy Person wraz z parametrami:
$pawel = new Person('Pawel', 'Kowalski');
$ola = new Person('Ola', Widera');
W przypadku gdy właściwości klasy (imiona osób) w momencie tworzenia obiektów nie są znane
i mają być ustalone dopiero w późniejszej fazie działania programu, bądź zajdzie potrzeba ich zmiany
na inne, wtedy parametr w konstruktorze ustawia się w inny sposób.
class Person
{
public $name;
public $surname;
public function __construct($name, $surname='')
{
$this->name = $name;
$this->surname = $surname;
}
public function setSurname($surname)
{
$this->surname = $surname;
}
2
…
}
$pawel = new Person('Pawel');
$ola = new Person('Ola', Widera');
echo $pawel->getName().'<br />';
//Wyświetlone zostanie Pawel
echo $ola->getName().'<br />';
//Wyświetlone zostanie Ola Widera
$pawel->setSurame('Kowalski');
$ola->setSurame('Rostocka');
echo $pawel->getName().'<br />';
echo $ola->getName().'<br />';
//Wyświetlone zostanie Pawel Kowalski
//Wyświetlone zostanie Ola Rostocka
Drugi parametr konstruktora posiada domyślną pustą wartość, w przypadku gdy nazwisko osoby
nie jest znane w momencie tworzenia obiektu. Za pomocą metody setSurname() można je
w późniejszej fazie działania programu ustawić bądź zmienić.
Dziedziczenie
Dziedziczenie, czyli przekazywanie swoich właściwości i metod klasom potomnym. Stworzoną
klasę przykładu Person można rozszerzać o nowe funkcjonalności poprzez dopisywanie nowych
metod. Można np. wysłać osobę do pracy przez utworzenie metody work(). Osoba jaką jest również
dziecko nie będzie pracować, dziecko za to będzie się uczyć, dla takiej sytuacji dobrym rozwiązaniem
jest wykorzystanie właściwości dziedziczenia. Dziecko podobnie jak dorosły posiada imię i nazwisko,
natomiast nie chodzi do pracy. Klasa główna, jaką jest Person będzie zawierała wszystkie metody
i właściwości wspólne dla wszystkich klas potomnych. Klasy potomne po odziedziczeniu będą
zawierały wszystkie metody i właściwości klasy głównej oraz będą mogły posiadać własne metody
i właściwości unikalne dla danej klasy. Warto także zapamiętać, że podczas dziedziczenia od klasy
głównej wszystkie metody i właściwości publiczne dalej są dostępne wewnątrz klasy potomnej jak
i na zewnątrz niej. Natomiast wszystkie metody prywatne w klasie głównej nie są dostępne na
zewnątrz klasy jak również wewnątrz klasy potomnej. Aby klasa potomna miała dostęp do wybranych
pól z klasy głównej, nawet tych, których nie widać na zewnątrz klasy to w klasie bazowej dla tych pól
należy ustawić modyfikator dostępu protected.
W PHP 5 każda klasa może dziedziczyć tylko po jednej klasie. Aby dana klasa dziedziczyła po innej
klasie należy po nazwie tej klasy dopisać słowo kluczowe extends, po którym podaje się nazwę klasy
bazowej, po której klasa potomna ma dziedziczyć.
class Person
//klasa bazowa
{
protected $age;
//właściwość dostępna również w klasie potomnej
private $name;
//właściwość dostępna wyłącznie w klasie głównej
public function __construct($name ='')
{
$this->name = $name;
}
public function setName($name)
…
public function getName()
3
…
}
class Child extends Person
{
private $school;
//klasa potomna
public function __construct($name = '') {
parent::__ construct($name = '')
$this->school = 'SP nr 18';
}
public function goToPrimarySchool()
{
echo 'chodzę do szkoły podstawowej '.$this->school;
}
}
$pawel = new Person('Paweł Kowalski');
$ola = new Child('Ola Widera');
echo $pawel->getName().'<br />';
//zostanie wyświetlone: Paweł Kowalski
echo $ola->getName().'<br />';
//zostanie
wyświetlone:
Ola
Widera
$ola->goToPrimarySchool()
//zostanie wyświetlone: chodzę do szkoły podstawowej SP nr 18
Próba wywołania metody goToSchool()na obiekcie klasy Person zgłosi błąd gdyż tylko obiekt
klasy Child może chodzić do szkoły. W klasie potomnej konstruktor klasy głównej został przysłonięty
przez konstruktor klasy potomnej przez co nie został wykonany. Aby wywołać konstruktor klasy
głównej należy użyć słowa kluczowego parent. To samo tyczy się innych metod w klasie potomnej.
W wielu zastosowaniach podstawowa klasa bazowa jest na tyle ogólna, że nie powinno się
tworzyć obiektu takiej klasy. Aby zapobiec tworzeniu obiektów klas ogólnych wprowadzono w PHP 5
słowo kluczowe abstract.
abstract class GeometricalFigure() {…}
Aby zmusić klasy potomne do implementacji konkretnej metody wystarczy w klasie głównej
utworzyć metodę i poprzedzić ją słowem kluczowym abstract, wtedy klasa potomna (jeśli nie jest
klasą abstrakcyjną) musi zaimplementować tą metodę i wypełnić ją ciałem.
abstract class GeometricalFigure {
abstract public function surfaceArea();
}
abstract class Triangle extends GeometricalFigure {
private $p;
public function surfaceArea($a, $h)
{
$this->p = $a * $h;
echo 'Pole powierzchni trójkąta jest równe '.$this->p;
}
}
4
Metody oraz właściwości statyczne
Właściwości oraz metody klasy mogą być statyczne. Do pól statycznych można się odwoływać
bezpośrednio pomijając tworzenie obiektu danej klasy. Aby odwołać się do właściwości statycznej
bądź uruchomić metodę statyczną wewnątrz klasy, należy ją poprzedzić słowem kluczowym self,
natomiast aby się odwołać to takiej zmiennej lub metody na zewnątrz klasy wtedy należy poprzedzić
je nazwą klasy.
class ClassName
{
static public $staticProperty;
static public function staticMethod()
{
echo self::$staticProperty;
}
}
ClassName::staticProperty = 'właściwość statyczna';
ClassName::staticMethod();
Obie linie powyższego kodu spowodują wyświetlenie treści: właściwość statyczna. Właściwości
statyczne mogą być wykorzystane do zliczania liczby utworzonych obiektów danej klasy.
class Counter {
static private $number = 0;
public function __construct() {
self::$number++;
}
public function getNumber() {
return self::$number;
}
}
$l1 = new Counter();
$l2 = new Counter ();
$l3 = new Counter ();
echo 'Liczba obiektów: '.$l1->getNumber().'<br />';
$l4 = new Counter ();
$l5 = new Counter ();
echo 'Liczba obiektów: '.$l1-> getNumber().'<br />'
//Liczba obiektów: 3
//Liczba obiektów: 5
Pola statyczne wykorzystywane są we wzorcu projektowym Singleton, który umożliwia
utworzenie tylko jednej instancji danej klasy.
class Singleton {
static private $instance = null;
private $text = '';
static public function create() {
if (self::$instance == null) {
self::$instance = new Singleton();
}
return self::$obiekt;
}
public function setText($text) {
5
$this->text = $text;
}
public function getText() {
return $this->text;
}
private function __construct() {}
private function __clone() {}
}
$obiekt1 = Singleton::create();
echo 'Obiekt 1: '.$obiekt1->getText().'<br />'; // wyświetlone zostanie: Obiekt 1:
$obiekt1->setText('Jestem jedynym obiektem!');
echo 'Obiekt 1: '.$obiekt1->getTekst().'<br />';
// wyświetlone zostanie: Obiekt 1: Jestem jedynym obiektem!
$obiekt2 = Singleton::create();
echo 'Obiekt 2: '.$obiekt2->getText().'<br />';
// wyświetlone zostanie: Obiekt 2: Jestem jedynym obiektem!
$obiekt2->setText('Ja naprawdę jestem jedynym obiektem!');
echo 'Obiekt 1: '.$obiekt1->getText().'<br />';
// wyświetlone zostanie: Obiekt 1: Jestem naprawdę jestem jedynym obiektem!
echo 'Obiekt 2: '.$obiekt2->getText().'<br />';
// wyświetlone zostanie: Obiekt 2: Jestem naprawdę jestem jedynym obiektem!
Dzięki temu, że konstruktor i metoda do klonowania obiektu (metoda, która jest domyślnie
wywoływana gdy następuje próba klonowania obiektu) jest prywatna to nie można ich użyć do
utworzenia nowego obiektu. Jedynym sposobem na utworzenie obiektu tej klasy jest uruchomienie
metody statycznej create(), która najpierw sprawdza czy właściwość statyczna $instance
zawiera już obiekt klasy Singleton. Jeśli nie zawiera to tworzy ten obiekt i przypisuje go do
właściwości $instance. Następnie wartość właściwości $instance czyli utworzony, jedyny obiekt
klasy Singleton jest zwracany przez tą metodę statyczną.
Interface
Podczas projektowania struktury klas przydatne są również interfejsy. Interfejsy reprezentują
klasy abstrakcyjne, tzn. zawierają tylko i wyłącznie deklaracje metod oraz właściwości. W interfejsie
nie można używać modyfikatorów dostępu gdyż wszystkie pola muszą być publiczne. Aby utworzyć
interfejs należy użyć słowa kluczowego interface, po którym następuje nazwa interfejsu.
interface ExemplaryInterface {
$property;
function method1();
function method2();
}
Interfejs może dziedziczyć wyłącznie od innych interfejsów. Ilość dziedziczonych interfejsów jest
nieograniczona. Aby dziedziczyć od innego interfejsu to po nazwie interfejsu potomnego wystarczy
dopisać słowo kluczowe extends, po którym podaje się listę nazw innych interfejsów separując je
przecinkiem.
6
interface ChildInterface extends ExemplaryInterface, OtherInterface {
function childMethod();
}
Klasy mogą implementować interfejsy w nieograniczonej liczbie. Implementacja interfejsu polega
na tym, że klasa, która implementuje dany interfejs musi posiadać metody i właściwości publiczne
określone w implementowanym interfejsie. Interfejsy, które implementuje klasa określa się poprzez
dodanie po nazwie klasy słowa kluczowego implements, po którym podaje się listę nazw
implementowanych interfejsów separując je przecinkiem.
class ExemplaryClass implements ExemplaryInterface {
public $property;
public function method1() {
//...
}
public function method2() {
//...
}
}
Jeśli klasy implementują ten sam interfejs, oznacza to, że posiadają wszystkie metody
i właściwości zadeklarowane w danym interfejsie.
7

Podobne dokumenty