Menu
Coddy logo textTech

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 за пределами иерархии классов. Эта защита гарантирует, что конфиденциальные данные можно изменять только через контролируемые методы.

МодификаторТот же classchild classВне класса
publicДаДаДа
protectedДаДаНет
privateДаНетНет

Ключевой момент: Используйте private для внутренних данных, к которым не следует обращаться directly, protected — для данных, необходимых child classes, а public — only для безопасного внешнего access.

challenge icon

Задание

Легко

Давайте создадим безопасную систему управления сотрудниками, демонстрирующую, как модификаторы доступа защищают конфиденциальные данные. Вы создадите иерархию классов, в которой разные уровни информации доступны в зависимости от того, где выполняется код: внутри class, в child class или извне.

Вы организуете код в трёх файлах:

  • Employee.php: Создайте Employee class, который управляет данными сотрудника с соответствующими уровнями видимости. У class должны быть:
    • public property $name для имени сотрудника (безопасно для всеобщего просмотра)
    • protected property $employeeId для внутреннего идентификатора (необходимо для child classes)
    • private property $salary для конфиденциальной информации об оплате (только этот class должен иметь к нему прямой доступ)
    Constructor должен принимать все три значения и присваивать их. Добавьте public method getSalary(), который возвращает private salary. Это контролируемый способ доступа к protected данным. Также добавьте public method getPublicInfo(), который возвращает "[name] works here".
  • Manager.php: Создайте Manager class, который extends Employee. Подключите файл Employee. Constructor должен принимать name, employeeId, salary и название department. Вызовите parent constructor с первыми тремя значениями, затем сохраните department в private property. Добавьте public method getTeamInfo(), который возвращает "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()
?>
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор PHP