Модификаторы доступа в PHP
Модификаторы доступа - это, по сути, интерпретация инкапсуляции в ООП. Напоминаю, что инкапсуляция - это механизм сокрытия реализации объекта. Простой пример из жизни. Многие из Вас ездят в метро, и Вы сначала проходите через турникеты, прикладывая к ним специальный билет. Затем, если на Вашем билете ещё остались поездки, то турникет Вас пропускает, а если нет, то пищит и не пропускает. Вы задумывались над тем, почему так происходит? Вы задумывались над тем, как он определяет, сколько поездок ещё осталось, как он подаёт сигналы на открытие или подаёт сигнал на писк? Я думаю, что большинство из Вас даже об этом не думало. Почему? Да, потому что реализация для Вас скрыта. Всё, что Вы видите так это то, что турникет работает и всё. А как он работает Вы не знаете, и самое главное, что Вы и знать не должны. Вот это и есть пример инкапсуляции - сокрытие реализации объекта от объекта, который его использует. И для реализации инкапсуляции существуют модификаторы доступа в PHP.
В PHP имеется три модификатора доступа:
- Public
- Protected
- Private
Начнём с модификатора доступа public. Данный модификатор означает, что свойство, метод или конструктор будут доступны для всех объектов, которые их используют.
Модификатор доступа protected означает, что данный элемент объекта может быть использован только в самом объекте, а также в его дочерних.
И, наконец, модификатор доступа private означает, что данный элемент объекта может быть использован только в самом объекте и нигде больше.
Давайте продолжим заниматься классами по автомобилям и реализуем их заново, но с использованием модификаторов доступа. Напоминаю, что раньше мы использовали только public, что не есть хорошо. Итак, абстрактный класс, отвечающий за "Автомобиль":
<?php
abstract class Car {
protected $x;
protected $y;
public function __construct($x, $y) {
$this->x = $x;
$this->y = $y;
}
abstract public function move ($x, $y);
abstract protected function sound();
}
?>
Как видите, мы сделали свойства объекта Car защищёнными (protected), то есть они теперь доступны только внутри самого класса Car, а также во всех его наследниках. Также мы закрыли служебную функцию sound(), сделав её также protected. Всё остальное (конструктор и метод move()) мы оставили открытыми, то есть public. Иногда всё-таки бывает нужно иметь доступ к свойствам, однако, делать их открытыми совсем не хочется. Тогда добавляют так называемые методы get и set:
<?php
abstract class Car {
protected $x;
protected $y;
public function __construct($x, $y) {
$this->x = $x;
$this->y = $y;
}
public function getX() {
return $this->x;
}
public function getY() {
return $this->y;
}
public function setX($x) {
$this->x = $x;
}
public function setY($y) {
$this->y = $y;
}
abstract public function move ($x, $y);
abstract protected function sound();
}
?>
Таким образом, мы теперь можем спокойно получать полный доступ ко всем свойствам на чтение и на запись.
Теперь класс "Auto", отвечающий за легковой автомобиль:
<?php
require_once "car.php";
class Auto extends Car {
public function move($x, $y) {
$this->sound();
echo "Движение легкового автомобиля из координат ($this->x, $this->y) в координаты ($x, $y)<br />";
$this->x = $x;
$this->y = $y;
}
protected function sound() {
echo "Звук движения легкового автомобиля<br />";
}
}
?>
Здесь мы поменяли модификатор доступа только у метода sound().
И, наконец, скрипт, который использует объект Auto.
<?php
require_once "auto.php";
$auto = new Auto(10, 20);
echo $auto->getX();
echo "<br />";
$auto->setY(5);
echo $auto->getY();
echo "<br />";
echo $auto->move(15, 15);
?>
Здесь мы создали объект Auto. Потом получили доступ к его свойству X (напоминаю, что модификатор доступа стоит protected, поэтому писать так нельзя: $auto->x; - будет ошибка). Затем меняем значение свойства Y на 5. А после вызываем метод движения. Вы можете всё проверить и убедиться, что всё работает как швейцарские часы.
Таким образом, мы с Вами привели код нашей программы к наилучшему варианту. Возможно, Вы спросите: "А где использовать модификатор доступа private?". Используйте его всегда, если у Вашего объекта не будет наследников. Главное, чтобы Вы понимали чётко: служебные методы (то есть методы, которые не будут использоваться за пределами класса) - в private (или protected), а методы, которые будут использоваться за пределами класса, необходимо пометить как public. Что касается конструктора, то Вы можете его пометить как private, если не хотите, чтобы можно было создать объект (такое часто бывает нужно, например, при реализации шаблона Singleton, когда от одного класса может быть создан лишь один объект на всю программу, впрочем, это уже другая история). А со свойствами поступайте так: если свойство используется за пределами класса очень часто, то делайте его public, если не используется вообще, то private (или protected). Если свойство используется, но достаточно редко, то сделайте его private (или protected), но также реализуйте методы get и set. Вот и всё.
Вообще, ООП - это очень сложная вещь. И для того, чтобы оценить его преимущество на практике, необходимо много работать с ним. И, разумеется, модификаторы доступа - это то, без чего ООП потеряло бы почти всякий смысл. И когда Вы освоите ООП, то просто не сможете без него программировать вообще. И очень надеюсь, что я сегодня ещё немного приблизил Вас к этому моменту.
-
- Михаил Русаков
Комментарии (21):
Создавал класс для страницы, и в нем получилось много полей(титл, дескрипшн, тело и т.д) хотел написать функцию которая бы в качестве параметра получала нужный элемент страницы и получала его, так как эта идея показалась мне гораздо более разумной чем писать гет методы для каждого поля. Сейчас покажу что я делал: public function get_something($param) { return $this->$param; } конечно же функция не сработала(из за того что после -> стоит знак $) вопрос такой, возможно ли вообще реализовать то что я хочу(то есть get метод для произвольного поля класса) средствами php?
Ответить
Сразу в поля записать то, что в GET не получится. Но можно вручную это сделать. То есть принять массив и сразу его значения раскидать по полям. А уже потом обычными методами вытаскивать эти значения из полей.
Ответить
Ясно, а если делать для каждого поля свой метод, это не сильно скажется на быстродействии?
Ответить
На быстродействие это практически не повлияет.
Ответить
<?php require_once "car.php"; class Auto extends Car { public function move($x, $y) { $this->sound(); echo "Движение легкового автомобиля из координат ($this->x, $this->y) в координаты ($x, $y)<br />"; $this->x = $x; $this->y = $y; } protected function sound() { echo "Звук движения легкового автомобиля<br />"; } } ?> У вас не закрашен!
Ответить
Спасибо, исправил!
Ответить
Михаил, Вы написали "В PHP имеются три модификаторы доступа". Может быть, Вы имели в виду "три модификатора доступа"?
Ответить
Спасибо, исправил!
Ответить
В php есть default modificator как на Jave?
Ответить
Да, это public.
Ответить
У вас ошибка тут "Начнём с модификаторы доступа public"
Ответить
Спасибо, исправлено.
Ответить
Михаил, а зачем вообще нужно скрывать код ?
Ответить
Для реализации механизма инкапсуляции.
Ответить
Ну а инкапсуляция зачем нужна ?
Ответить
Тут написано: http://myrusakov.ru/oop-javascript.html
Ответить
123
Ответить
123
Ответить
<img class="avatar" src="/images/avatars/user_1.jpeg" alt="Admin">
Ответить
<script type="text/javascript"> alert(111); </script>
Ответить
<<script type="text/javascript"> alert(111); </script>
Ответить
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.