Метод доступа PHP5 позволяет ограничить доступ к членам класса. Это новая функция PHP5, но она уже давно существует во многих объектно-ориентированных языках. С помощью методов доступа вы можете разработать надежное объектно-ориентированное приложение и создать повторно используемую объектно-ориентированную библиотеку классов.
Подобно C++ и Java, PHP имеет три метода доступа: общедоступный, частный и защищенный. Метод доступа для члена класса может быть одним из них. Если вы не укажете метод доступа, по умолчанию вы также можете указать метод доступа. Статические члены определяют метод доступа. Поместите метод доступа перед ключевым словом static (например, public static).
Доступ к открытым членам возможен без ограничений. Любой код вне класса может читать и записывать общедоступные свойства. сценарий. Вызовите общедоступный метод где угодно. В предыдущих версиях PHP все методы и свойства были общедоступными, поэтому объекты выглядели как красиво структурированные массивы.
Закрытые члены видны только внутри класса. Вы не можете изменить или прочитать значение частного свойства вне метода класса, в котором оно находится. Аналогично, только методы одного и того же класса могут вызывать частный метод, а унаследованные подклассы не могут получить доступ к частным членам родительского класса.
Обратите внимание, что к закрытым членам может получить доступ любой член класса и экземпляры класса. В примере 6.8 метод Equals сравнивает два виджета. Оператор == сравнивает два объекта одного и того же класса, но в этом примере каждый экземпляр объекта имеет уникальный идентификатор. Метод Equals сравнивает только имя и цену. Обратите внимание, как метод Equals обращается к частному свойству другого экземпляра Widget. И Java, и C позволяют это.
Листинг 6.8. Закрытые члены
класса Widget
{
личное $имя;
частная $цена;
частный $id
общедоступная функция __construct($name, $price);
{
$this->name = $name;
$this->price = floatval($price);
$this->id = uniqid();
}
//проверяет, являются ли два виджета одним и тем же public functionquals($widget)
{
return(($this->name == $widget->name)AND ($this->price == $widget->price));
}
}
$w1 = новый виджет('Cog', 5.00);
$w2 = новый виджет('Cog', 5.00);
//ИСТИНА
);
если($w1->равно($w2))
{
print("w1 и w2 — это одно и то же n");
}
//ЛОЖЬ
если($w1->равно($w3))
{
print("w1 и w3 — это одно и то же n");
}
//FALSE, == включает в сравнение идентификатор
if($w1 == $w2) //не равны, поскольку идентификаторы разные
{
print("w1 и w2 — это одно и то же n");
}
?>
Если вы новичок в объектно-ориентированном программировании, вы можете задаться вопросом, какова цель использования частных членов. Возможно, вы помните идеи инкапсуляции и связи, которые мы обсуждали в начале этой главы. Закрытые члены помогают инкапсулировать данные. Они могут быть скрыты внутри класса от доступа к ним со стороны кода вне класса. Они также помогают добиться слабой связи. Если код вне структуры данных не может напрямую получить доступ к внутренним свойствам, неявной корреляции нет.
Конечно, большинство частных свойств по-прежнему могут использоваться внешним кодом. Решение состоит в том, чтобы использовать пару общедоступных методов: один — get (получить значение свойства), другой — установить (установить значение свойства). Конструкторы также принимают начальные значения свойств. Это позволяет осуществлять связь между членами через узкий, квалифицированный интерфейс. Это также дает возможность изменять значения, передаваемые в метод. Обратите внимание на пример 6.8, как конструктор приводит. Сделать цену числом с плавающей запятой (floadval()).
Доступ к защищенным (защищенным) членам могут получить все методы одного и того же класса и все методы унаследованных классов. Открытые свойства противоречат духу инкапсуляции, поскольку позволяют подклассам использовать определенное свойство для записи. Защищенные методы не вызывают такой проблемы. Подкласс, использующий защищенный метод, должен хорошо знать структуру своего родительского класса. .
Пример 6.9 улучшен по сравнению с примером 6.8 и включает подкласс Thing от Widget. Обратите внимание, что у Widget теперь есть защищенный метод getName. Если экземпляр Widget попытается вызвать защищенный метод, произойдет ошибка: $w1->getName() генерирует ошибку, но метод getName в подклассе Thing может вызвать этот защищенный метод. Конечно, этот пример слишком прост, чтобы доказать, что метод Widget::getName защищен. В реальных ситуациях использование защищенного метода зависит от понимания внутренней структуры объекта.
Листинг 6.9. Защищенные члены
класса Widget
{
личное $имя;
частная $цена;
частный $id
общедоступная функция __construct($name, $price);
{
$this->name = $name;
$this->price = floatval($price);
$this->id = uniqid();
}
//проверяем, одинаковы ли два виджета
публичная функция равна ($ виджет)
{
return(($this->name == $widget->name)AND($this->price == $widget->price));
}
защищенная функция getName()
{
возврат ($ это-> имя);
}
}
Класс Thing расширяет виджет
{
частная $color
общедоступная функция setColor($color);
{
$this->color = $color;
}
Публичная функция getColor()
{
return ($this->color);
}
Публичная функция getName()
{
return(родитель::getName());
}
}
$w1 = новый виджет('Cog', 5.00);
$w2 = новая вещь('Cog', 5.00);
$w2->setColor('Yellow');
//ИСТИНА (все еще!) Результат по-прежнему верен
если($w1->равно($w2))
{
print("w1 и w2 — это одно и то же n");
}
//печатаем вывод Cog Cog
print($w2->getName());
?>
Подкласс может изменить метод доступа к методу, переопределив метод родительского класса. Однако все же существуют некоторые ограничения. Если вы переопределяете общедоступный член класса, он должен оставаться общедоступным в своих подклассах. Если вы переопределяете защищенный член, он может оставаться защищенным или становиться общедоступным. Частные члены по-прежнему будут видны только в текущем классе. Объявление члена с тем же именем, что и частный член родительского класса, просто создаст другой член в текущем классе. Поэтому технически вы не можете переопределить закрытый член.
Ключевое слово Final — это еще один способ ограничить доступ к методам-членам. Подклассы не могут переопределять методы, помеченные как окончательные в родительском классе, а ключевое слово Final нельзя использовать для атрибутов.