Приватные и защищенные свойства
Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy — урок 18 из 91.
До сих пор мы использовали свойства public, к которым можно получить доступ отовсюду. Но иногда вам нужно ограничить доступ, чтобы защитить свои данные. PHP предоставляет два дополнительных модификатора видимости: private и protected.
К свойству private можно получить доступ только из класса, который его определяет:
<?php
class BankAccount {
private $balance = 0;
public function deposit($amount) {
$this->balance += $amount;
}
public function getBalance() {
return $this->balance;
}
}
$account = new BankAccount();
$account->deposit(100);
echo $account->getBalance();
Вывод:
100Попытка доступа к $account->balance напрямую извне класса приведет к ошибке. Это защищает баланс от изменения без использования метода deposit.
Свойство protected работает аналогично, но к нему также могут обращаться дочерние классы, которые расширяют родительский:
<?php
class User {
protected $email;
public function __construct($email) {
$this->email = $email;
}
}
class Admin extends User {
public function showEmail() {
return $this->email;
}
}
$admin = new Admin("admin@example.com");
echo $admin->showEmail();
Вывод:
admin@example.comКлючевой момент: Используйте private, когда только определяющий класс должен иметь доступ к свойству. Используйте protected, когда дочерним классам также нужен доступ. Оба модификатора предотвращают прямой внешний доступ, сохраняя внутреннее состояние вашего объекта в безопасности.
Задание
ЛегкоДавайте создадим безопасную систему управления сотрудниками, которая демонстрирует, как защитить конфиденциальные данные с помощью свойств private и protected.
Вы создадите три файла, которые работают вместе для управления информацией о сотрудниках с надлежащим контролем доступа:
Employee.php— Определите классEmployee, который служит базой для всех сотрудников. Он должен иметь свойствоprotected $name(чтобы дочерние классы могли получить к нему доступ) и свойствоprivate $salary(только этот класс должен напрямую изменять зарплату). Конструктор принимает имя и зарплату, устанавливая оба свойства. Добавьте публичный методgetName(), который возвращает имя, публичный методgetSalary(), который возвращает зарплату, и публичный методgiveRaise($amount), который увеличивает зарплату на указанную сумму.Manager.php— Определите классManager, который расширяетEmployee. Подключите файл Employee в начале. Добавьте приватное свойство$department. Конструктор должен принимать имя, зарплату и отдел — вызовите родительский конструктор для имени и зарплаты, затем установите отдел. Создайте методgetDetails(), который возвращает"[name] manages [department]", обращаясь к защищенному свойству$nameнапрямую. Также добавьте методgetDepartment(), который возвращает отдел.main.php— Подключите оба файла классов. Создайте объектManagerс именем"Sarah", зарплатой75000и отделом"Engineering". Выведите детали менеджера с помощьюgetDetails(). Затем дайте менеджеру прибавку в размере5000и выведите его новую зарплату с помощьюgetSalary(). Каждый вывод должен быть на новой строке.
Обратите внимание, как класс Manager может напрямую обращаться к защищенному свойству $name, но должен использовать метод getSalary() для доступа к приватной зарплате. Это демонстрирует ключевое различие между видимостью protected и private: protected разрешает доступ дочерним классам, в то время как private сохраняет данные по-настоящему скрытыми.
Шпаргалка
PHP предоставляет три модификатора видимости для свойств класса:
public— доступен отовсюдуprivate— доступен только внутри определяющего классаprotected— доступен внутри определяющего класса и дочерних классов
Приватные свойства:
class BankAccount {
private $balance = 0;
public function deposit($amount) {
$this->balance += $amount;
}
public function getBalance() {
return $this->balance;
}
}К приватным свойствам нельзя обратиться напрямую извне класса. Используйте публичные методы для взаимодействия с ними.
Защищенные свойства:
class User {
protected $email;
public function __construct($email) {
$this->email = $email;
}
}
class Admin extends User {
public function showEmail() {
return $this->email; // Дочерний класс может получить доступ к защищенному свойству
}
}Защищенные свойства могут быть доступны дочерним классам, которые расширяют родительский класс.
Когда использовать:
- Используйте
private, когда только определяющий класс должен иметь доступ к свойству - Используйте
protected, когда дочерним классам также нужен доступ - Оба модификатора предотвращают прямой внешний доступ, защищая внутреннее состояние объекта
Попробуйте сами
<?php
require_once 'Employee.php';
require_once 'Manager.php';
// TODO: Создайте менеджера с именем "Sarah", зарплатой 75000 и отделом "Engineering"
// TODO: Выведите данные менеджера, используя getDetails()
// TODO: Увеличьте зарплату менеджера на 5000
// TODO: Выведите новую зарплату, используя getSalary()
?>В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово $thisМетодыСвойстваКонструктор (__construct)Деструктор (__destruct)Итоги — Простой калькулятор4Наследование
Основы наследованияКлючевое слово parent::Переопределение методовКлючевое слово finalАбстрактные классыИтоги — Иерархия сотрудников7Инкапсуляция
Public, Protected, PrivateПодробный разбор модификаторов доступаГеттеры и сеттерыСокрытие данныхConstructor Promotion (8.0)Итоги — Система учета студентов10Продвинутые концепции ООП
Композиция против наследованияВнедрение зависимостейАнонимные классыПеречисления (PHP 8.1)Файберы (PHP 8.1)Глубокое погружение в клонирование объектовГенераторы и итераторы13Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикПаттерн Репозиторий2Пространства имен и автозагрузка
Введение в пространства именКлючевое слово useСтандарт автозагрузки PSR-4Автозагрузчик ComposerИтоги: структурированный проект5Интерфейсы и контракты
Введение в интерфейсыРеализация интерфейсовРеализация нескольких интерфейсовИнтерфейс против абстрактного классаType Hinting с интерфейсамиИтоги — Калькулятор фигур8Магические методы
Введение в магические методы__toString и __debugInfo__get, __set, __isset, __unset__call и __callStatic__clone и клонирование объектов__serialize и __unserializeИтоги — Кастомная коллекция11Система типов и обработка ошибок
Объявление типовNullable-типыТипы объединения и пересеченияКлассы исключенийИерархия пользовательских исключенийTry, Catch, FinallyИтоги — Валидатор форм14Проект: Управление библиотекой
Обзор проектаКлассы Book и User3Свойства классов
Свойства экземпляра и статические свойстваКонстанты в классахСтатические методы и свойстваПриватные и защищенные свойстваСвойства Readonly (PHP 8.1)Итоги — Менеджер банковского счета6Полиморфизм
Снова о переопределении методовПолиморфизм через интерфейсыType Hinting и Union TypesПозднее статическое связываниеИтоги — Payment Processor9Трейты
Введение в трейтыИспользование нескольких трейтовРазрешение конфликтов трейтовАбстрактные методы в трейтахТрейты и наследование12Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн ObserverПаттерн Strategy