Инкапсуляция в объектно-ориентированном программировании на PHP

Инкапсуляция в объектно-ориентированном программировании на PHP

От автора: до сих пор мы с Вами, при создании методов и свойств, объявляли их как public, то есть абсолютно открытыми, что не совсем хорошо. Поэтому в данной статье, мы рассмотрим оставшиеся два спецификаторы доступа, а также изучим последний основной принцип, который был пропущен, под названием — инкапсуляция в ООП на PHP.

Итак, хотел бы напомнить, что элементы класса, могут быть объявлены, как:

public – открытые, или общедоступные;

protected – защищенные;

private – закрытые.

Доступ к общедоступным свойствам или методам открыт из абсолютно любого контекста. То есть, создав объект интересующего класса, Вы всегда можете считать или изменить значение свойств, объявленный как public, а так же обратиться к методам, у которых определен данный спецификатор доступа.

По большому счету мы с Вами это уже рассматривали и не однократно использовали на практике, но повторение, как Вы знаете, ни когда не бывает лишним.

К защищенным элементам класса доступ извне, то есть из объекта, получить нельзя. Разрешается обращаться к указанным свойствам или методам из класса, в котором они определены, либо из его подклассов.

Таким образом, если мы в предыдущем примере, объявим свойство $title, используя спецификатор доступа protected — попытка обращения к нему, через объект, незамедлительно приведет к ошибке. Но при этом, мы знаем, что можно обращаться к подобному свойству, из класса, в котором оно определено, а значит, никто не запрещает определить открытый метод, который будет возвращать значение интересующего свойства.

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

Защищенные свойства и методы, так же доступны и в классах наследниках.

При этом к закрытым свойствам или методам можно получить доступ, только из того класса в котором они определены и не более. Таким образом, если в последнем примере, в родительском классе объявить свойство $title, со спецификатором доступа private – интерпретатор PHP вернет ошибку, так как, повторюсь, из дочернего класса нельзя обращаться к закрытым свойствам.

Конечно же, возникает вопрос, зачем все это нужно? Смотрите, спецификаторы доступа, или как их еще называют, ключевые слова определяющие область видимости, позволяют предоставлять доступ только к тем элементам класса, которые необходимы для конкретного клиента. Соответственно контроль доступа, благодаря которому можно запретить доступ к некоторым элементам класса, помогает избежать не правильной, работы приложения в целом.

Теперь давайте рассмотрим следующий пример. Предположим, что разрабатывается интернет магазин, а значит работать необходимо с товарами, для которых определяется цена, при этом, как правило, механизм ценообразования достаточно сложен, но мы его упростим и условимся, что окончательная цена товара, будет формироваться из некого значения базовой цены, а так же с учетом ставки налогообложения. Поэтому в самом простом виде, создадим следующий класс.

Данный класс это как бы основа, которая была создана, одним определенным человеком и далее используя его, другие члены команды будут формировать функционал будущего приложения. При этом класс определяет метод getPriceTovar(), как доступ к окончательной цене товара. Соответственно, что бы получить вышеуказанную цену необходимо сделать следующее:

Как Вы видите, в принципе все очень просто, есть цена, и есть метод, который ее формирует. Но есть небольшая проблема, которая заключается в том, что можно обратиться напрямую к свойству $price, в том случае если оно объявлено как открытое. И в этом случае, налог не будет учитываться для формирования окончательной цены, а значит, приложение будет работать не корректно. Что бы избежать этого, необходимо объявить свойство $price, со спецификатором доступа private, тем самым доступ к свойству, будет разрешен, только из метода getPriceTovar().

Но, в тоже время, уровень видимости private, так же запрещает доступ к свойству из дочерних классов, что приводит к тому, что мы не сможем создать подкласс, и переопределить метод getPriceTovar(), для несколько иной манипуляции над свойством $price. К примеру, если нужно для некоторой группы товаров, вообще не использовать налог при формировании цены, то мы могли бы переопределить метод getPriceTovar():

Но данный код приведет к ошибке, потому как свойство $price, закрыто для всех дочерних классов.

А значит, объявляя данное свойство в родительском классе, более правильно, использовать спецификатор доступа protected и тем самым предоставить доступ к нему дочерним классам.

Из этого вытекает небольшая рекомендация по проектированию структуры класса. Сначала определите все свойства и методы как закрытые, а далее по мере написания кода и необходимости ослабляйте ограничения. Лучше лишний раз закрыть элемент класса, чем ошибочно предоставить больший уровень видимости, чем это необходимо.

Теперь мы с Вами плавно подошли к последнему ключевому понятию, под названием — инкапсуляция.

В объектно-ориентированном программировании на PHP инкапсуляцией называют свойство классов скрывать собственную реализацию. И, по сути, в простейшем виде, мы с Вами только что инкапсулировали данные, используя спецификаторы доступа protected и private и тем самым закрывали, или лучше сказать скрывали свойство $price от клиентского кода. То есть, при этом задается некий интерфейс доступа к данным и по большому счету, зная его, нам абсолютно все равно как устроен конкретный класс, так как мы знаем какие методы в нашем распоряжении и как их необходимо использовать, тем самым предотвращается некорректная работа с данными класса.

При этом полиморфизм, предполагает и реализует несколько другую инкапсуляцию в объектно-ориентированном программировании на PHP и означает, то что, размещая различные реализации определенного интерфейса, Вы скрываете работающий на его основе код. Таким образом, можно создавать новые классы, или редактировать существующие и это не приведет к ошибкам. Значение имеет только интерфейс, а не конкретный механизм который работает на его основе.

На этом данная статья завершена. Всего Вам доброго и удачного кодирования!!!

Метки:

Похожие статьи:

Комментарии Вконтакте:

Комментарии (2)