Konstruktor w PHP

Czym jest konstruktor?

Zaufaj intuicji.

Bazując na nazwie można się domyślić, że konstruuje obiekt naszej klasy.

Jest to po prostu specjalna metoda (funkcja), która uruchamia się za każdym razem, gdy tworzymy nowy obiekt danej klasy. Jak każda inna metoda, może przyjmować argumenty lub być bezargumentowa. Nie może jednak niczego zwracać.

Jak wygląda konstruktor?

Jest to metoda o nazwie __consruct(lista argumentów). Wykona się z automatu w momencie tworzenia obiektu.

Zobacz, jak wygląda w kodzie:

<?php
class Samochod {
  private $polePrywatne;

  public function __construct() {
    $this->polePrywatne = "test";
  }

  public function pobierzPole() {
    return $this->polePrywatne;
  }
}

$samochod = new Samochod();
echo $samochod->pobierzPole(); //wyświetli test
?>

Zauważ, że funkcja __construct wykonała się, mimo iż nie wywoływaliśmy jej jawnie w kodzie. PolePrywatne otrzymało nową wartość.

Co ciekawe, w niemal wszystkich pozostałych językach programowania konstruktory są metodami o identycznej nazwie co nazwa klasy. W PHP do pewnego momentu też stosowano taką konwencję, jednak z czasem metoda __construct wzięła górę.

W php wersji 5, jeśli interpreter nie odnajdzie metody __construct, poszuka metody o nazwie identycznej jak nazwa klasy i wykona ją podczas tworzenia. Jednak w php7 metody o nazwie klasy nie będą już traktowane jako konstruktory.

Zobacz przykład:

<?php
class Samochod {
  private $polePrywatne;

  public function Samochod() {
    $this->polePrywatne = "test";
  }

  public function pobierzPole() {
    return $this->polePrywatne;
  }
}

$samochod = new Samochod();
echo $samochod->pobierzPole(); //wyświetli test na php5, jednak już nie w php7
?>

Ma to służyć ujednoliceniu podejścia i niejako wymuszeniu na programistach stosowania jednego rodzaju konstruktora. Ma to swoje zalety, gdyż zmieniając nazwę klasy nie musisz się już martwić zmianą nazwy we wszystkich konstruktorach oraz ich wywołaniach.

Wiele konstruktorów

W wielu językach programowania (jak np. C++, C#, JAVA) możemy mieć kilka konstruktorów dla jednej klasy. To wszystko w zależności od potrzeb. Z racji swojej natury, PHP udostępnia nam stworzenie tylko jednego konstruktora. Nic nie stoi jednak na przeszkodzie, by samemu stworzyć mechanizm wielu konstruktorów. Jednak podczas tworzenia obiektu wykona się tylko jeden, jeśli świadomie nie wykonasz dodatkowo innego. Bardzo często nie jest to potrzebne.

To, który konstruktor się wykona, zależy od parametrów jakie mu podasz. Poniżej przykład z kilkoma konstruktorami:

<?php
class Samochod {
  private $polePrywatne;

  function __construct() 
  { 
     $this->polePrywatne = 'test';
     $a = func_get_args(); 
     $i = func_num_args(); 
     if (method_exists($this,$f='__construct'.$i)) { 
            call_user_func_array(array($this,$f),$a); 
     } 
  }

  public function __construct1($tresc) {
    $this->polePrywatne = $tresc;
  }

  public function __construct2($tresc, $czyZamienicNaWielkieLitery) {
    $trescDoKonstruktora = $czyZamienicNaWielkieLitery ? ucwords($tresc) : $tresc;
    $this->__construct1($trescDoKonstruktora); // wywołanie innego konstruktora
  }

  public function pobierzPole() {
    return $this->polePrywatne;
  }
}

$samochod = new Samochod();
echo $samochod->pobierzPole(); //wyświetli test
$samochod2 = new Samochod("osobowy");
echo $samochod2->pobierzPole(); //wyświetli osobowy
$samochod3 = new Samochod("osobowy", true);
echo $samochod3->pobierzPole(); //wyświetli Osobowy
?>

Po co stosujemy konstruktory?

Przede wszystkim po to, by nasz obiekt uzyskał odpowiedni stan. Najczęściej ustawiamy pożądane pola wg przekazanych parametrów.

Zobacz poniższy przykład:

<?php
class User {
  private $imie;
  private $nazwisko;
  private $email;

  public function __construct($imie, $nazwisko, $email) {
    $this->imie = $imie;
    $this->nazwisko = $nazwisko;
    $this->email = $email;
  }
}

$user = new User("Jan", "Kowalski", "jan@kowalski.pl");
?>

Konstruktor kopiujący

W programowaniu występuje też takie pojęcie jak konstruktor kopiujący (z ang. Copy constructor).

Jego głównym zadaniem jest utworzenie obiektu na bazie innego obiektu, kopiując jego pola.

Zobacz przykład:

<?php
class Samochod {
  private $marka;
  private $model;
  private $silnik;

  public function __construct($marka, $model, $silnik) {
    $this->marka = $marka;
    $this->model = $model;
    $this->silnik = $silnik;
  }

  public function __construct($samochod) {
    $this->marka = $samochod->marka;
    $this->model = $samochod->model;
    $this->silnik = $samochod->silnik;
  }
}

$samochod = new Samochod("Opel", "Insignia", "diesel");
$samochod2 = new Samochod($samochod); // samochod2 będzie miał identyczne dane co samochod
?>

To wszystko na temat konstruktorów, czym chciałem się z Tobą podzielić.

Dzięki tej lekcji potrafisz:

  • Napisać własny konstruktor
  • Napisać różne konstruktory i sterować ich wykonaniem przez przekazane argumenty
  • Wykonać konstruktor z kodu
  • Napisać konstruktor kopiujący

Teraz czas poznać pola i metody abstrakcyjne oraz statyczne. Będzie się działo!

Zapraszam!

Spis lekcji w programowaniu obiektowym

Poprzednia lekcja: Dziedziczenie Następna lekcja: Metody statyczne, abstrakcyjne i interfejsy