Abstrakcja i statyczność – klasy, metody

Metody abstrakcyjne

Wiesz już co nieco o dziedziczeniu.

Czas poszerzyć zdobytą wiedzę o metody abstrakcyjne. To specjalnie zdefiniowane metody, które nie posiadają własnej implementacji. Jednak wymuszają zaimplementowanie ich w każdej klasie dziedziczącej.

Klasa, która posiada choćby jedną metodę abstrakcyjną, nazywana jest klasą abstrakcyjną.

Z najważniejszych rzeczy – nie możesz utworzyć obiektu klasy abstrakcyjnej!

Jedyne, co możesz z nią zrobić to zdefiniować klasę, która będzie dziedziczyć po klasie abstrakcyjnej. Taka klasa musi definiować własną implementację każdej metody abstrakcynej, która znajdowała się w klasie bazowej.

Traktuj klasy abstrakcyjne jak swojego rodzaju szablon, na podstawie którego możesz tworzyć bardzo podobne klasy.

Zobacz przykład z pojazdami:

<?php
abstract class Pojazd {
  private $wlasciciel;

  public function setWlasciciel($wlasciciel) {
    $this->wlasciciel = $wlasciciel;
  }

  public function getWlasciciel() {
    return $this->wlasciciel;
  }

  abstract public function jedz();
}

class Samochod extends Pojazd {
  public function __construct($wlasciciel) {
    $this->setWlasciciel($wlasciciel);
  }

  public function jedz() {
    echo "Jedzie samochod";
  }
}

class Rower extends Pojazd {
  public function jedz() {
    echo "Jedzie rower";
  }
}

$samochod = new Samochod("Marcin");
$rower = new Rower();
$samochod->jedz(); // wyświetli Jedzie samochod
$rower->jedz(); // wyświetli Jedzie rower
?>

Klasy abstrakcyjne wyznaczają część wspólną dla podobnych klas, jednak same z siebie nie mogą zaistnieć w postaci obiektu. Są bardzo przydatne, gdyż pozwalają uniknąć duplikowania kodu i wymusić spójność między podobnymi klasami.

Interfejsy

Alternatywą oraz uzupełnieniem dla klasy abstrakcyjnej są interfejsy.

Interfejs to zestaw pól i metod, które klasa musi zaimplementować na własny sposób.

Zobacz jak to wygląda w praktyce:

<?php
interface iSamochod
{
  function jedz();
  function tankuj($ilePaliwa);
}

class Maluch implements iSamochod {
  private $iloscPaliwa;

  public function jedz() {
    echo "Maluch się toczy";
  }

  public function tankuj($ilePaliwa) {
    $this->iloscPaliwa += $ilePaliwa;
    if ($this->iloscPaliwa > 21)
      echo "Przelany";
  }
}

class Porshe implements iSamochod {
  public function jedz() {
    echo "Porshe jedzie bardzo szybko";
  }

  public function tankuj($ilePaliwa) {
    if ($ilePaliwa < 10)
      echo "Jeździsz Porshe, a na benzynę Cię nie stać?";
  }
}

Niezaimplementowanie którejkolwiek metody z wymienionych w interfejsie spowoduje Fatal Error i program się wysypie. Dzięki temu wiesz, że jeśli któraś klasa implementuje dany interfejs, to na pewno można na niej wywołać metodę tego interfejsu.

Jedno z ulubionych pytań na rozmowie rekrutacyjnej z PHP dotyczy różnic między interfejsem a klasą abstrakcyjną.

Obie konstrukcje służą do wymuszania konkretnych pól i metod w klasach z nich korzystających. Jakie natomiast są między nimi różnice?

Najważniejszą jest: klasa może dziedziczyć tylko po jednej klasie abstrakcyjnej, podczas gdy może implementować wiele interfejsów. I jeszcze: klasa abstrakcyjna może definiować ciało metody i wartości domyślne dla pól, a interfejs jedynie deklaruje pola i metody (podajesz tylko nazwy metod i pól oraz listę parametrów).

Metody statyczne

Drugim typem niestandardowych metod są metody statyczne.

Słowo kluczowe static oznacza, że metoda może zostać wywołana bez inicjalizacji obiektu danej klasy.

Po prostu, nie musisz tworzyć obiektu, by skorzystać z metody.

Zobacz przykład:

<?php
class Samochod {
  public static function czyJestNowy($rocznik) {
    return $rocznik == date('Y') ? true : false;
  }
}

echo Samochod::czyJestNowy(2017) ? "Nowy samochód" : "Przynajmniej roczny";
?>

Zobacz, jak odwołujesz się do zdefiniowanej metody statycznej. Musisz podać nazwę klasy, dwa dwukropki, po czym nazwę metody.

Pamiętaj, że w metodzie statycznej nie możesz odnosić się do pól, które nie są statyczne.

Jest to zrozumiałe, gdyż wartości pól niestatycznych nadawane są w istniejącym obiekcie, podczas gdy do pól i metod statycznych odwołujesz się bez istniejącego obiektu. Wynika z tego, że metoda lub pole statyczne nie ma wiedzy o konkretnym obiekcie, który tworzysz.

Metody statyczne są bardzo szeroko używane w najbardziej popularnym na świecie frameworku PHP, jakim jest Laravel. Dobrze je zapamiętaj, bo Laravel zdecydowanie jest warty poznania. Przy jego pomocy, tworzenie aplikacji webowych nabiera niezłego tempa.

Po tej lekcji potrafisz:

  • zadeklarować klasę i metodę abstrakcyjną
  • stworzyć definicję klasy dziedziczącej po klasie abstrakcyjnej
  • napisać własny interfejs
  • stworzyć klasę implementującą interfejs
  • stworzyć metodę statyczną
  • skorzystać z metody statycznej w kodzie PHP

Tym sposobem dobrnęliśmy do końca nauki programowania obiektowego. Serdecznie gratuluję!

Teraz czas zmierzyć się z realnymi problemami i napisać własną aplikację w PHP.

Spis lekcji w programowaniu obiektowym

Poprzednia lekcja: Konstruktory Następna lekcja: Praktyczne PHP