Public, Private И Protected: управление доступом к классам в ООП PHP

Опубликовал read-php в 13.01.2011 Категория: Основные сведения об объектах php

До сих пор мы явно или неявно объявляли все свойства как publiс (общедоступ­ные). Такой тип доступа задан по умолчанию для всех методов, а также свойств, объявленных с использованием устаревшего ключевого слова var.

Элементы класса можно объявить как public , private или protected.

  • К общедоступным свойствам и методам можно получать доступ из любого контекста.
  • К закрытому свойству и методу можно получить доступ только из того клас­са, в котором они объявлены. Даже подклассы данного класса не имеют дос­тупа к таким свойствам и методам.
  • К защищенным свойствам и методам можно получить доступ либо из содер­жащего их класса, либо из его подкласса. Никакому внешнему коду такой доступ не предоставляется.

Чем это может быть нам полезно? Ключевые слова, определяющие область ви­димости, позволяют показывать только те аспекты класса, которые требуются кли­енту. Это позволяет создать ясный и понятный интерфейс для объекта.

Контроль доступа, позволяюпщй запрещать клиенту доступ к некоторым свой­ствам. поможет также избежать ошибок в коде. Давайте, например, предположим, что мы хотим сделать так, чтобы в объектах типа ShopProduct поддерживались скидки. Для этого можно добавить свойство $discount и метод setDiscount ().

// Класс ShopProduct…

public $discount =0;

// …

function setDiscount( $num ) { $this->discount=$num;

}

Вооруженные механизмом определения скидки, мы можем создать метод getPrice (), который принимает во внимание примененную скидку.

// Класс ShopProduct…

function getPricef) {

return ($this->price – $this->discount);

}

Но тут у нас есть проблема. Мы хотим показать всем только скорректированную цену, но клиент может легко обойти метод getPrice () и получить доступ к свойст­ву $price.

print «Цена – {$productl->price}\n»;

В результате будет выведена исходная цена, а не цена со скидкой, которую мы хотим представить. Чтобы предотвратить это, можно просто закрыть свойство $price. Это позволит запретить клиентам прямой доступ к нему, заставляя ис­пользовать метод getPrice (). Любая попытка получить доступ к свойству $price из-за пределов класса ShopProduct закончится неудачей. В результате для внеш­него мира это свойство прекратит существование.

Но определение свойств как private — не всегда удачная стратегия, поскольку тогда дочерний класс не сможет получить доступ к закрытым свойствам. А теперь представьте, что правила вашего бизнеса таковы: при покупке только книг, на них скидку делать нельзя. Мы можем переопределить метод getPrice (), чтобы он воз­вращал свойство $price без применения скидки.

// Класс BookProduct

function getPrice() { return $this->price;

}

Поскольку свойство $price объявлено в классе ShopProduct, а не в BookProduct, попытка в приведенном выше коде получить к нему доступ закончится неудачей. Чтобы решить эту проблему, нужно объявить свойство $price защищенным (protected) и тем самым предоставить доступ к нему дочерним классам. Помните, что к защищенному свойству или методу нельзя получить доступ из-за пределов иерархии того класса, в котором это свойство или метод были объявлены. Доступ к ним можно получить только из исходного класса или его дочерних классов.

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

Комментариев нет

Добавить комментарий