Главная Новости

Закрытый конструктор в PHP


Опубликовано: 06.09.2018

видео Закрытый конструктор в PHP

PHP Essential. Урок 5. Инкапсуляция. Ключевое слово «final»

В этой статье рассмотрим пример использования закрытого конструктора, то есть снабдим его спецификатором доступа "private".



Если конструктор использует спецификатор доступа "private", то объект не будет создан при помощи оператора "new", так как попытка его объявления закончиться фатальной ошибкой:

"Call to private <имя класса>::__construct() from invalid context"

Однако это вовсе не означает, что объект такого класса вообще невозможно создать. Можно воспользоваться конструктором при помощи открытого метода данного класса.


61 - Уроки PHP. Google Sheets API

Создадим класс "byCoordinat" с закрытым конструктором, моделирующий точку в двумерной декартовой системе координат.

class byCoordinat { private $_cooX, $_cooY; private function __construct ($_coox, $_cooy) { $this->_cooX = $_coox; $this->_cooY = $_cooy; } public function coo_X() { return $this->_cooX; } public function coo_Y() { return $this->_cooY; } public function coo_new ($_coox, $_cooy) { return new byCoordinat($_coox, $_cooy); } }

Как видно, класс "byCoordinat" содержит дополнительный метод "coo_new()", который и вызывает конструктор.


Как создать форму с загрузкой файла?

$_Class_byCoordinat = byCoordinat::coo_new(1, 10); echo $_Class_byCoordinat->coo_X() .' | '. $_Class_byCoordinat->coo_Y(); # Результат: 1 | 10;

Зачем может потребоваться инициализация объекта в обход оператора "new"?

Главным образом, для увеличения гибкости приложения. Пусть, например, в большом вычислительном приложении создаются десятки тысяч точек в двумерной декартовой системе координат. В какой-то момент принимается решение добавить новый класс "myCoordinat" для трёхмерной системы координат, конструктор которого принимает три координаты: $_cooX, $_cooY и $_cooZ. Просто заменить класс "byCoordinat" новым нельзя, часть точек в проекте остаётся двумерной, а двумерные и трёхмерные точки следует рассматривать как несовместимые типы, то есть их классы должны различаться. Если для создания класса на протяжении всего проекта использовался оператор "new", то пришлось бы просмотреть и отредактировать все точки создания объектов "byCoordinat". Если же используется фабричный метод, можно переопределить только метод "coo_new()".

Приёмы и алгоритмы, связанные с возвращением объектов при помощи одного из методов, называются "Фабричными":

class byCoordinat { private $_cooX, $_cooY; private function __construct ($_coox, $_cooy) { $this->_cooX = $_coox; $this->_cooY = $_cooy; } public function coo_X() { return $this->_cooX; } public function coo_Y() { return $this->_cooY; } public function coo_new($_coox, $_cooy, $_cooz = 'false') { if ($_cooz == 'false') { return new byCoordinat($_coox, $_cooy); } else { return new myCoordinat($_coox, $_cooy, $_cooz); } } }

Как видно из примера, в метод "coo_new" добавлен третий необязательный параметр для координаты "Z". Это достаточно просто сделать, а на существующих вызовах наличие ещё одного, необязательного параметра не как не отразится, так как для создания двумерных точек используется только первые два параметра.

Если параметр "$_cooz" не задаётся разработчиком, он получает значение "false", а метод "coo_new()" создаёт объект класса "byCoordinat". Если же параметр задан, то создаётся объект класса "myCoordinat", и далее класс "byCoordinat" не участвует в работе объекта.

Предоставленный приём сокрытия создания объекта также является примером инкапсуляции, только на более высоком уровне абстракции. В полной мере, достоинства данного приёма можно оценить при использовании интерфейсов и наследования.

rss