В терминологии ООП творится довольно серьёзная путаница. Она возникает в первую очередь из-за того, что многие программируют либо на одном языке, либо если и на разных, то часто схожих по структуре языках. Соответственно, происходит профессиональная деформация, когда программист видит мир сквозь призму одного языка. Одна из таких историй происходит вокруг инкапсуляции и сокрытия данных (data hiding). Напомню, что сокрытие данных — подход, при котором нельзя изменить данные напрямую, в обход интерфейса, тем самым нарушив инварианты (такое происходит не всегда). Есть языки, в которых присутствует сокрытие данных, например, Haskell, но нет инкапсуляции. В ООП сокрытие данных появляется благодаря двум возможностям:
- инкапсуляции
- области видимости свойств
Однако учтите, в литературе часто отождествляют термины инкапсуляция и сокрытие данных. Поэтому не пугайтесь, если многие вокруг вас будут утверждать, что инкапсуляция — это про сокрытие данных (защиту), но даже не вспомнят про объединение функций и данных в рамках одной структуры.
Достаточно изменить ключевое слово public
на private
у любого свойства, как пропадёт возможность обращаться к нему напрямую снаружи объекта.
<?php
class Point
{
private $x;
private $y;
public function __construct($x, $y)
{
// Внутри по-прежнему доступ есть
$this->x = $x;
$this->y = $y;
}
public function getX()
{
return $this->x;
}
public function getY()
{
return $this->y;
}
}
$point = new Point(10, 8);
print_r($point->getX()); // => 10
$point->x; // PHP Fatal error: Uncaught Error: Cannot access private property Point::$x<Paste>
Подчеркну, что речь идёт именно о доступе снаружи. Внутри он должен остаться, иначе как мы сможем оперировать этим свойством?
Сокрытие данных считается важным атрибутом любой абстракции, независимо от того, работаем мы в ООП-стиле, или нет. Именно по этой причине существуют геттеры. В ООП, построенном на классах, вообще не принято обращаться к свойствам напрямую. Геттеры — первое, что реализуется при описании любого нового класса. Кстати, в языке Ruby нельзя (один способ есть, но он выходит за рамки обсуждаемой темы) обратиться к свойству объекта без геттера, но описываются они там значительно проще и компактнее, чем в таких языках, как PHP или Java, и выглядят как обращения к свойствам (в Ruby можно не ставить скобки при вызове функций). То же самое касается и сеттеров. Свойства напрямую не редактируют, так как потенциально можно нарушить инварианты.
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.