background image

1

Podstawy programowania II

dr inż. Paweł Róg  

background image

2

Zagadnienia

Podstawy programowania obiektowego

Klasy i obiekty.

Pola i metody.

Dostęp do składowych, hermetyzacja.

Konstruktory i destruktory.

Typy argumentów funkcji i metod.

Dziedziczenie.

Zagadnienia zaawansowane

Pola i metody statyczne.

background image

3

Klasa

Definicja klasy w języku PHP5

class

 nazwa_klasy 

{

// ciało klasy

}

Klasa jest to złożony typ będący opisem (definicją) pól 

i metod  obiektów  (opis  zbioru  wszystkich  obiektów 

mających wspólną strukturę i zachowanie).

Klasa jest to złożony typ będący opisem (definicją) pól 

i metod  obiektów  (opis  zbioru  wszystkich  obiektów 

mających wspólną strukturę i zachowanie).

background image

4

Obiekt

Tworzenie obiektu w PHP5

$nazwa_zmiennej = 

new

 nazwa_klasy();

Obiekt  jest  konkretyzacją  (instancją)  danej  klasy 

i wypełnieniem  wzorca,  jakim  jest  klasa,  określonymi 

danymi. Obiekt posiada tożsamość, stan i zachowanie.

Obiekt  jest  konkretyzacją  (instancją)  danej  klasy 

i wypełnieniem  wzorca,  jakim  jest  klasa,  określonymi 

danymi. Obiekt posiada tożsamość, stan i zachowanie.

background image

5

Pola

Stan obiektu jest określony przez wartości pól 
obiektu
. Pola obiektu to zmienne przechowywane 
wewnątrz obiektu.

class Zarowka {
   

private $zapalona

;

}

background image

6

Metody

Zachowanie obiektu jest określone przez 
metody. Metody są funkcjami zdefiniowanymi 
wewnątrz klasy.

class Zarowka {
   private $zapalona;

   

public function zapal() {

      $this->zapalona = True;

   

}

}  

background image

7

Hermetyzacja

Poziomy dostępu

public – składowa klasy jest dostępna z dowolnego 

miejsca programu. Metody są domyślnie publiczne, 

chyba, że programista zdecyduje inaczej.

protected – składowa klasy jest dostępna w danej 

klasie i jej klasach pochodnych.

private – składowa klasy jest dostępna tylko w klasie, 

w której została zdefiniowana.

Hermetyzacja  pozwala  na  ukrycie  pewnych  danych 

i funkcji 

obiektu 

przed 

bezpośrednim 

dostępem 

z zewnątrz.

Hermetyzacja  pozwala  na  ukrycie  pewnych  danych 

i funkcji 

obiektu 

przed 

bezpośrednim 

dostępem 

z zewnątrz.

background image

8

Dostęp do składowych

Aby uzyskać dostęp do składowych klasy, należy 
posłużyć się operatorem 
-> (minus i znak 
większości, bez spacji)

class prosta {

   

public

 $publiczna;

}

function test() {
   $obiekt = new prosta();

   $obiekt

->

publiczna = 123;

   print $obiekt

->

publiczna;

}

background image

9

Dostęp do składowych

Oczywiście z zewnątrz klasy możliwy jest jedynie 
dostęp do składowych publicznych, dlatego 
w przypadku poniższego kodu otrzymamy błąd:

class prosta {
   

private

 $prywatna;

}

function test() {
   $obiekt = new prosta();

   $obiekt->prywatna = 123; // 

błąd !!!

   print $obiekt->prywatna; // 

błąd !!!

}

background image

10

Wynik działania skryptu

Fatal error: Cannot access private property prosta::
$prywatna in 
C:\wamp\www\skrypty\prosta.php on 
line 
8

background image

11

Dostęp do składowych

class SzukamGuza {

   

public

 $problem; 

// nie ustawiać

                    

// na True !!!

   public function bum() {

      if ($this->problem == True) 
         print 'BUM !!!';

   }
}

function test() {

   $poCoToRobic = new SzukamGuza();
   $poCoToRobic->problem = 

True

;

   $poCoToRobic->bum();
}

background image

12

Wynik działania skryptu

BUM !!!

background image

13

$this

Dostęp do składowych z metod klasy odbywa się 
za pomocą specjalnej zmiennej 
$this, która 
odnosi się do aktualnego obiektu.

class Zarowka {

   private $zapalona;
   public function zapal() {

      

$this

->zapalona = True;

   }
   public function zgas() {

      

$this

->zapalona = False;

   }

}

background image

14

Dostęp do definicji klasy

Aby móc używać klasy, która jest zdefiniowana 
w innym pliku, należy plik, w którym jest 
zdefiniowana klasa, załadować za pomocą 
require_once

require_once 'nazwa_pliku.php';

background image

15

Powtórzenie

Pole jest to zmienna wewnątrz obiektu.

Metoda jest to funkcja wewnątrz klasy.

Wszystkie pola klasy muszą być zadeklarowane 
i poprzedzone jednym ze słów kluczowych 
określających ich widoczność: 
public
protected lub private.

W przypadku definiowania metod, określenie ich 
widoczności jest opcjonalne, lecz polecane. 
Domyślnie metody są publiczne.

Aby klasa była widoczna wewnątrz pliku, który 
z niej korzysta, należy załadować plik, w którym 
jest zdefiniowana z wykorzystaniem 
require_once

background image

16

Powtórzenie

Do tworzenia obiektów klasy służy słowo kluczowe 
new

Zmienna $this wewnątrz klasy odnosi się do 
aktualnego obiektu

Dostęp do składowych (pól i metod) klasy 
zapewnia operator 
->

Uzyskując dostęp do pola klasy za pomocą 
operatora 
-> opuszczamy znak $ przed nazwą 
pola

Próba dostępu do składowej chronionej lub 
prywatnej spoza klasy spowoduje błąd

Dostęp do pól prywatnych możemy zapewnić za 
pomocą publicznych metod klasy

background image

17

Konstruktor

W PHP5 nazwa konstruktora __construct() 
rozpoczyna się od dwóch znaków podkreślenia „
_

class Zarowka {
   private $zapalona;

   public function 

__construct

($stan) {

      $this->zapalona = $stan;

   }
}

Konstruktorem

 nazywamy 

specjalną 

metodę 

automatycznie wywoływaną w trakcie tworzenia obiektu, 

pozwalającą  na  nadanie  początkowych  wartości  danym 

obiektu.

Konstruktorem

 nazywamy 

specjalną 

metodę 

automatycznie wywoływaną w trakcie tworzenia obiektu, 

pozwalającą  na  nadanie  początkowych  wartości  danym 

obiektu.

background image

18

Destruktor

W PHP5 nazwa destruktora __destruct() 
rozpoczyna się od dwóch znaków podkreślenia „
_

class Zarowka {
   private $zapalona;

   public function 

__destruct

() {

      print 'I po żarówce ...';

   }
}

Destruktorem

 nazywamy 

specjalną 

metodę 

bezparametrową,  która  jest  wywoływana  zawsze 

w momencie usuwania obiektu

Destruktorem

 nazywamy 

specjalną 

metodę 

bezparametrową,  która  jest  wywoływana  zawsze 

w momencie usuwania obiektu

background image

19

Przykład 1

class Zarowka {
   private $zapalona;
   public function __construct() {
      print 'Oto zgaszona żarówka !!!<br />';
      $this->zapalona = False;
   }
   public function __destruct() {
      print 'I po żarówce ...<br />';
   }
   public function zapal() {
      print 'Zapalam żarówkę...<br />';
      $this->zapalona = True;
   }
   public function zgas() {
      print 'Gaszę żarówkę...<br />';
      $this->zapalona = False;
   }

background image

20

Przykład 1 cd.

   public function stan() {
      return $this->zapalona;
   }
}

function opis($zr) {
   print 'Żarówka jest ';
   if ($zr->stan()) print 'zapalona.<br />';
      else print 'zgaszona.<br />';
}

function test() {
   $zr = new Zarowka();
   $zr->zapal();
   opis($zr);
   $zr->zgas();
}

   

background image

21

Wynik działania skryptu

Oto zgaszona żarówka !!!
Zapalam żarówkę...
Żarówka jest zapalona.
Gaszę żarówkę...
I po żarówce ...

background image

22

Typy argumentów funkcji

Co się stanie, jeśli w poprzednim przykładzie 
zapomnimy o znaku „
$” i napiszemy:

function test() {
   $zr = new Zarowka();
   $zr->zapal();
   opis(

zr

);

   $zr->zgas();
}

Otrzymamy mniej więcej następujące błędy:

Notice: 

Use of undefined constant zr - assumed 'zr'

 

in C:\wamp\www\skrypty\zarowka.php on line 33

Fatal error: 

Call to a member function stan() on a 

non-object

 in C:\wamp\www\skrypty\zarowka.php on 

line 25

background image

23

Typy argumentów funkcji

Można tę sytuację zmienić określając 
typ argumentu przyjmowanego przez funkcję 
opis() 

function opis(

Zarowka

 $zr) {

   if ($zr->stan()) print "zapalona.";
      else print "zgaszona.";
}

Otrzymamy wtedy następujący błąd:

Catchable fatal error: 

Argument 1 passed to opis() 

must be an instance of Zarowka, string given

, called 

in C:\wamp\www\skrypty\zarowka.php on line 33 and 
defined in C:\wamp\www\skrypty\zarowka.php on line 
25

background image

24

Typy argumentów funkcji

Na pierwszy rzut oka wydaje się, że sytuacja 
uległa pogorszeniu, jednak zyskujemy to, że:

Błąd zostaje wykryty wcześniej – w momencie 

przekazania obiektu do funkcji, a nie w momencie jego 

użycia

Błąd jest typu „

Catchable fatal error

”, co 

przy wykorzystaniu mechanizmu wyjątków umożliwia 

nam utrzymanie kontroli nad przebiegiem wykonania 

programu

background image

25

Przykład 2

 class Lampa {
    

protected

 $zarowka;

    public function __construct (Zarowka $zarowka) {
       print 'Wkręcam żarówkę<br />';
       $this->zarowka = $zarowka;
    }
    public function zapal() {
       $this->zarowka->zapal();
       print 'Lampa zapalona<br />';
    }
    public function zgas() {
       $this->zarowka->zgas();
       print 'Lampa zgaszona<br />';
    }
}

background image

26

Dziedziczenie

Dziedziczenie pozwala na powtórne 
wykorzystanie istniejącego kodu, ponieważ klasa 
pochodna dziedziczy po klasie bazowej pola 
i metody.

class pochodna 

extends

 bazowa {

   // ciało klasy pochodnej

}

Dziedziczenie  jest  operacją  polegającą  na  stworzeniu 

nowej  klasy  (pochodnej)  na  bazie  klasy  już  istniejącej 

(bazowej). 

Dziedziczenie  jest  operacją  polegającą  na  stworzeniu 

nowej  klasy  (pochodnej)  na  bazie  klasy  już  istniejącej 

(bazowej). 

background image

27

Przykład 3

class LampkaNocna 

extends

 Lampa {

   private $sciemniacz;

   public function __construct (Zarowka $zarowka) {

      

parent::__construct($zarowka);

      $this->sciemniacz= new Sciemniacz($this->zarowka);

   }

   public function rozjasnij() {

      $this->sciemniacz->rozjasnij();

   }

   public function sciemnij() {

      $this->sciemniacz->sciemnij();

   }

}

Zapis

parent::

__construct($zarowka);

oznacza wywołanie konstruktora klasy bazowej (Lampa

i przekazanie mu wartości zmiennej $zarowka.

background image

28

Przykład 3 cd.

 class Sciemniacz {

    private $zarowka;

    private $poziomJasnosci = 100;

    public function __construct (Zarowka $zarowka) {

       $this->zarowka = $zarowka;

    }

    public function rozjasnij() {

       if ($this->poziomJasnosci < 100) {

          $this->poziomJasnosci++;

          print 'Rozjaśniam światło żarówki<br>';

       }

    }

    public function sciemnij() {

       if ($this->poziomJasnosci > 1) {

          $this->poziomJasnosci--;

          print 'Przyciemniam światło żarówki<br>';

       }

    }

 }

background image

29

Przykład 3 cd.

$zarowka = new Zarowka();

$lampka = new LampkaNocna($zarowka);
$lampka->zapal();
$lampka->rozjasnij();

$lampka->sciemnij();
$lampka->sciemnij();

$lampka->rozjasnij();
$lampka->rozjasnij();

$lampka->rozjasnij();
$lampka->zgas();

background image

30

Wynik działania skryptu

Oto zgaszona żarówka !!!
Wkręcam żarówkę
Zapalam żarówkę...
Lampa zapalona
Przyciemniam światło żarówki
Przyciemniam światło żarówki
Rozjaśniam światło żarówki
Rozjaśniam światło żarówki
Gaszę żarówkę...
Lampa zgaszona
I po żarówce ...

background image

31

Przykład 4

class LampaOgrodowa 

extends

 Lampa {

  private $czujnikRuchu;
  public function __construct (Zarowka $zarowka) 
     {
     parent::_construct($zarowka);
     $this->czujnikRuchu = new   
CzujnikRuchu($this->zarowka);
     $this->czujnikRuchu->uruchom();
     }
}

background image

32

Przykład 4 cd.

class CzujnikRuchu {
  private $zarowka;
  public __construct(Zarowka $zarowka) {
    $this->zarowka = $zarowka;
  }
  public function uruchom() {
    print 'Czujnik ruchu uruchomiony<br>';
    //wykrywanie ruchu...
  }
  private function wykrytoRuch() {
    print 'Wykryto ruch<br>';
    $this->zarowka->wlacz();
  }
  private function ruchZanikl() {
    print 'Ruch zanikl<br>';
    $this->zarowka->wylacz();
  }
}

background image

33

Przykład 5

function test(Lampa $lampa) {
  $lampa->zapal();
  $lampa->zgas();
}

$zarowka = new Zarowka();
$lampkaNocna = new LampkaNocna ($zarowka);
test($lampkaNocna);
print '<br>';
$lampaOgrodowa = new LampaOgrodowa 
($zarowka);
test($lampaOgrodowa);

background image

34

Wynik działania skryptu

Oto zgaszona żarówka !!!
Wkręcam żarówkę
Zapalam żarówkę...
Lampa zapalona
Gaszę żarówkę...
Lampa zgaszona

Wkręcam żarówkę
Czujnik ruchu uruchomiony
Zapalam żarówkę...
Lampa zapalona
Gaszę żarówkę...
Lampa zgaszona
I po żarówce ...

background image

35

Wiele klas pochodnych

Klasa pochodna może mieć tylko jedną klasę 
bazową, ale może być klasą bazową dla wielu 
klas pochodnych

class Samochod {
// ...
}

class SamochodCiezarowy 

extrends

 Samochod {

// ...
}

class SamochodOsobowy 

extrends

 Samochod {

// ...
}

background image

36

Nadpisywanie

Pola i metody dziedziczone z klasy bazowej mogą 
być nadpisywane w klasie pochodnej

class Zarowka {
   private $zapalona;
   public function __construct() {
      

print "Oto zgaszona żarówka !!!";

      $this->zapalona = False;
   }
   public function __destruct() {
      print "I po żarówce ...";
   }
   public function zapal() {
      print "Zapalam żarówkę...";
      $this->zapalona = True;
   }
// ...
}

background image

37

Nadpisywanie

class ZarowkaEnergooszczedna extends Zarowka {
   public function __construct() {
      parent::__construct();
      

print "Energooszczędna !!!";

   }
   public function __destruct() {
      parent::__destruct();
      print "Utylizacja ...";
   }
   public function zapal() {
      parent::zapal();
      print "Taniej !!!";
   }
// ...
}

background image

38

Składowe statyczne

Do deklarowania składowych statycznych służy 
słowo kluczowe 
static:

class Zarowka {
// ...
   private 

static

 $licznikZarowek = 0;

   public 

static

 function ileZarowek() {

      return $licznikZarowek;
   }
//...
}

Składowe  (pola  i  metody)  statyczne  są  to  składowe 

klasy,  które  nalezą  się  do  całej  klasy,  a  nie,  tak  jak 

zwykłe  składowe,  do  pojedynczej  instancji  (obiektu) 

klasy.

Składowe  (pola  i  metody)  statyczne  są  to  składowe 

klasy,  które  nalezą  się  do  całej  klasy,  a  nie,  tak  jak 

zwykłe  składowe,  do  pojedynczej  instancji  (obiektu) 

klasy.

background image

39

Składowe statyczne

Ponieważ składowe statyczne należą do całej 
klasy, a nie do konkretnego obiektu, można ich 
używać nawet wtedy, kiedy nie istnieje żaden 
obiekt danej klasy.

Dostęp do składowych statycznych zapewnia 
operator zasięgu „
::

print Zarowka

::

ileZarowek();

background image

40

Przykład 6

class Zarowka {
   

private static $licznikZarowek = 0;

   private $zapalona;
   public function __construct() {
      

print 'Oto zgaszona żarówka !!!<br>';

      $this->zapalona = False;
      

self::

$licznikZarowek++;

   }
   public function __destruct() {
      print 'I po żarówce ...<br>';

      self::

$licznikZarowek--;

   }
   public function zapal() {
      print 'Zapalam żarówkę...<br>';
      $this->zapalona = True;
   }
   public function zgas() {
      print 'Gaszę żarówkę...<br>';
      $this->zapalona = False;
   }

background image

41

Przykład 6 cd.

   public function stan() {
      return $this->zapalona;
   }
   

public static function ileZarowek() {

      return 

self::

$licznikZarowek;

   }

}

function test() {
   

// w tym momencie nie istnieje jeszcze żaden      

   // obiekt klasy Zarowka !!!
   print Zarowka::ileZarowek().'<br>';

   $zr = new Zarowka();
   

print Zarowka::ileZarowek().'<br>';

   $zr->zapal();
   $zr->zgas();
   $zr2 = new Zarowka();
   

print Zarowka::ileZarowek().'<br>';

}

background image

42

Wynik działania skryptu

0
Oto zgaszona żarówka !!!
1
Zapalam żarówkę...
Gaszę żarówkę...
Oto zgaszona żarówka !!!
2
I po żarówce ...
I po żarówce ...

background image

43

Powtórzenie

Aby zdefiniować klasę pochodną, należy 
wykorzystać słowo kluczowe 
extends podając 
nazwę klasy bazowej.

Klasa pochodna może mieć tylko jedną klasę 
bazową, ale może być klasą bazową dla wielu 
klas pochodnych.

Klasa pochodna ma dostęp do wszystkich 
składowych swojej klasy bazowej i jej klas 
bazowych (jeśli istnieją), z wyjątkiem składowych, 
które zostały zadeklarowane jako prywatne.

Pola i metody dziedziczone z klasy bazowej mogą 
być nadpisywane w klasie pochodnej.

background image

44

Powtórzenie

Dostęp do składowej klasy bazowej nadpisanej 
w klasie pochodnej można uzyskać za pomocą 
parent::

Aby zdefiniować składową w zasięgu klasy należy 
użyć 
static

Dostęp do składowych statycznych można 
uzyskać za pomocą 
parent::self:: lub 
nazwa_klasy
::


Document Outline