Public, Protected, Private
Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy. Урок 38 из 91.
Добро пожаловать в главу об инкапсуляции! Инкапсуляция заключается в контроле доступа к внутренним данным вашего class. PHP предоставляет три модификатора доступа, которые определяют, откуда можно получить доступ к свойствам и методам: public, protected и private.
Вот как работает каждый модификатор:
<?php
class BankAccount {
public $accountHolder; // Доступен из любого места
protected $accountNumber; // Доступен в этом классе и дочерних классах
private $balance; // Доступен только в этом классе
public function __construct($holder, $number, $balance) {
$this->accountHolder = $holder;
$this->accountNumber = $number;
$this->balance = $balance;
}
public function getBalance() {
return $this->balance;
}
}
$account = new BankAccount("John", "12345", 1000);
echo $account->accountHolder . "\n"; // Работает - public
echo $account->getBalance(); // Работает - public method
Вывод:
John
1000Попытка получить доступ к $account->balance напрямую вызовет ошибку, поскольку это private. То же самое относится к $account->accountNumber за пределами иерархии классов. Эта защита гарантирует, что конфиденциальные данные можно изменять только через контролируемые методы.
| Модификатор | Тот же class | child class | Вне класса |
|---|---|---|---|
public | Да | Да | Да |
protected | Да | Да | Нет |
private | Да | Нет | Нет |
Ключевой момент: Используйте private для внутренних данных, к которым не следует обращаться directly, protected — для данных, необходимых child classes, а public — only для безопасного внешнего access.
Задание
ЛегкоДавайте создадим безопасную систему управления сотрудниками, демонстрирующую, как модификаторы доступа защищают конфиденциальные данные. Вы создадите иерархию классов, в которой разные уровни информации доступны в зависимости от того, где выполняется код: внутри class, в child class или извне.
Вы организуете код в трёх файлах:
Employee.php: СоздайтеEmployeeclass, который управляет данными сотрудника с соответствующими уровнями видимости. У class должны быть:publicproperty$nameдля имени сотрудника (безопасно для всеобщего просмотра)protectedproperty$employeeIdдля внутреннего идентификатора (необходимо для child classes)privateproperty$salaryдля конфиденциальной информации об оплате (только этот class должен иметь к нему прямой доступ)
getSalary(), который возвращает private salary. Это контролируемый способ доступа к protected данным. Также добавьте public methodgetPublicInfo(), который возвращает"[name] works here".Manager.php: СоздайтеManagerclass, который extendsEmployee. Подключите файл Employee. Constructor должен принимать name, employeeId, salary и название department. Вызовите parent constructor с первыми тремя значениями, затем сохраните department в private property. Добавьте public methodgetTeamInfo(), который возвращает"Manager [name] (ID: [employeeId]) leads [department]". Обратите внимание, как child class может получить доступ к protected$employeeId, но для доступа к private salary ему потребуетсяgetSalary().main.php: Подключите файл Manager. Вы получите четыре входных значения: name, идентификатор employee, salary (в виде строки, которую вы преобразуете в целое число) и название department. Создайте экземплярManagerс этими значениями. Выведите три строки:- name manager, полученное напрямую (public property)
- результат calling
getTeamInfo() - результат calling
getSalary()
Этот challenge демонстрирует инкапсуляцию в действии: name находится в свободном доступе, employee ID доступен child classes благодаря protected видимости, а salary остаётся скрытым в parent class: доступным только через контролируемый public method.
Попробуйте сами
<?php
require_once 'Manager.php';
// Читать входные данные
$name = trim(fgets(STDIN));
$employeeId = trim(fgets(STDIN));
$salary = intval(trim(fgets(STDIN)));
$department = trim(fgets(STDIN));
// TODO: Создать экземпляр Manager с входными значениями
// TODO: Вывести имя менеджера (доступ напрямую как публичное свойство)
// TODO: Вывести результат вызова getTeamInfo()
// TODO: Вывести результат вызова getSalary()
?>В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово $thisМетодыСвойстваКонструктор (__construct)Деструктор (__destruct)Повторение — простой калькулятор4Наследование
Основы наследованияКлючевое слово parent::Переопределение методовКлючевое слово finalАбстрактные классыПовторение — иерархия сотрудников7Инкапсуляция
Public, Protected, PrivateМодификаторы доступа подробноГеттеры и сеттерыСокрытие информацииПродвижение конструктора (8.0)Повторение — система учёта студентов2Пространства имён и автозагрузка
Введение в пространства имёнКлючевое слово useСтандарт автозагрузки PSR-4Автозагрузчик ComposerПовторение — структурированный проект5Интерфейсы и контракты
Введение в интерфейсыРеализация интерфейсовРеализация нескольких интерфейсовИнтерфейс и абстрактный классАннотация типов с интерфейсамиПовторение — калькулятор фигур8Магические методы
Введение в магические методы__toString и __debugInfo__get, __set, __isset, __unset__call и __callStatic__clone и клонирование объектов__serialize и __unserializeПовторение — пользовательская коллекция3Свойства классов
Свойства экземпляра и статические свойстваКонстанты в классахСтатические методы и свойстваПриватные и защищённые свойстваСвойства только для чтения (PHP 8.1)Повторение — менеджер банковского счёта6Полиморфизм
Повторение переопределения методовПолиморфизм через интерфейсыАннотации типов и объединённые типыПозднее статическое связываниеПовторение — обработчик платежей9Трейты
Введение в трейтыИспользование нескольких трейтовРазрешение конфликтов трейтовАбстрактные методы в трейтахТрейты и наследование12Паттерны проектирования, часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн ObserverПаттерн StrategyПотренируйтесь самостоятельно: Онлайн-компилятор PHP