Привет всем читателям! Это первый эпизод сериала “Сущности ООП”. Здесь я расскажу о классах: что это и какие модификаторы они имеют – но поскольку о них можно поговорить побольше, то это всего лишь первая часть.
Классы
Как сообщает нам Википедия: класс – это шаблон для создания объекта; но мне более нравится: Класс – описание структуры объекта и методов работы с ним – оно более емкое. Если просто говорить – это набор свойств и методов, которые при использовании определенных модификаторов могут быть скрыты в объекте, а также вызваны без создания объекта; также есть вариант, что класс не может порождать объект – здесь мы все это и обсудим…
Класс, не умеющий рождать объект
Обычный класс делать это умеет(“Process finished with exit code 0” – говорит об отсутствии ошибок)
<?php class Page {} $page = new Page(); // OUTPUT: // Process finished with exit code 0
но если перед class
словом добавить abstract
– он потеряет данную возможность. Класс не умеющий рождать объекты? зачем? как с ними работать?
<?php abstract class Page {} $page = new Page(); // OUTPUT: // Fatal error: Uncaught Error: Cannot instantiate abstract class Page // Process finished with exit code 255
Начнем по порядку – зачем? Полазив на разных сайтах(блогах, форумах…), посмотрев разные мнения и учев свои опыт и взгляд – пришел к выводу – обеспечение полиморфизма классов(принципы OCP, LSP – реализация в виде паттернов); и, мало не забыл сказать, что важно – абстрактные классы могут содержать абстрактные свойства и методы(читай далее). Теперь как с ними играть: наследовать, наследовать и только наследовать!
<?php abstract class Page {} class MainPage extends Page {} $page = new MainPage(); // OUTPUT: // Process finished with exit code 0
Модификаторы доступности свойств и методов
И методы, и свойства имеют одинаковый набор модификаторов открывающих им определенную область видимости – public, рrotected и private. Первый модификатор(public)
<?php class Page { public $id; public function getId() { return $this->id; } } class MainPage extends Page { public function index() { $id = $this->id; $id = $this->getId(); } } $page = new MainPage(); $page->index(); $id = $page->getId(); $id = $page->id; // OUTPUT: // Process finished with exit code 0
открывает полную область – как внутри объекта класса и классов-наследников, так и при обращении к объекту вне класса; второй – только внутри себя
<?php class Page { protected $id; protected function getId() { return $this->id; } } class MainPage extends Page { public function index() { $id = $this->id; $id = $this->getId(); } } $page = new Page(); $page->index(); $id = $page->getId();// error $id = $page->id;// error // OUTPUT: // Fatal error: Uncaught Error: Call to protected method Page::getId() from context '' // line 23 // Process finished with exit code 255
и классов-наследников; и третий – только внутри себя.
<?php class Page { private $id; private function getId() { return $this->id; } } class MainPage extends Page { public function index() { $id = $this->id;// error $id = $this->getId();// error } } $page = new MainPage(); $page->index(); $id = $page->getId();// error $id = $page->id;// error // OUTPUT: // Fatal error: Uncaught Error: Call to private method Page::getId() from context 'MainPage' // line 17 // Process finished with exit code 255
Кстати, у функции(метода) класса слово отвечающее за область видимости может отсутствовать – тогда ее область видимости равна public.
Ключевые слова в свойствах и методах
С одним ключевым словом(abstract
) уже разобрались. Эти слова являются дополнительными(необязательными) инструкциями к тому, как работают свойства и методы. Начнем их рассмотрение с директивы static
– она позволяет доступ к активу не создавая объект; иначе говоря – прикрепляет функцию внутрь класса.
<?php class Page { public static $id; public static function getId() {} } Page::$id; Page::class; Page::getId(); $page = new Page(); $page::$id; $page::class; $page::getId(); // OUTPUT: // Process finished with exit code 0
Кста, внутри класса автоматически создаётся статическая публичная переменная class, содержащая имя класса с его неймспейсом.
И последний модификатор(для пхп) это final
– говорит о том, что при наследовании класса данный метод не возможно переопределить.