Модификаторы доступа подробно
Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy. Урок 39 из 91.
Теперь, когда вы понимаете три модификатора доступа, давайте рассмотрим, как они ведут себя в сценариях наследования. Главное, что нужно понять: члены с модификатором protected становятся доступными дочерним классам, а члены с модификатором private остаются скрытыми даже от дочерних классов.
<?php
class Vehicle {
public $brand;
protected $engineType;
private $serialNumber;
public function __construct($brand, $engine, $serial) {
$this->brand = $brand;
$this->engineType = $engine;
$this->serialNumber = $serial;
}
private function getSerial() {
return $this->serialNumber;
}
protected function getEngineInfo() {
return $this->engineType;
}
}
class Car extends Vehicle {
public function getDetails() {
return $this->brand . " - " . $this->getEngineInfo();
// $this->serialNumber вызовет ошибку - private!
// $this->getSerial() также не сработает - private method!
}
}
$car = new Car("Toyota", "V6", "ABC123");
echo $car->getDetails();
Вывод:
Toyota - V6Класс Car может получить доступ к $brand (public) и вызвать getEngineInfo() (protected), но не имеет доступа к $serialNumber или getSerial(), поскольку они private для Vehicle. Это различие позволяет делиться некоторыми внутренними деталями с дочерними классами, сохраняя другие полностью скрытыми.
Ключевой момент: Используй protected, когда дочерним классам нужен доступ к внутренним данным или методам, и private, когда даже дочерние классы не должны обращаться к определённым деталям реализации.
Задание
ЛегкоДавайте создадим систему управления устройствами, которая демонстрирует, как модификаторы доступа ведут себя при наследовании. Вы создадите базовый класс Device со свойствами разных уровней видимости, а затем расширите его с помощью класса Smartphone, показывающего, к каким членам дочерние классы могут и не могут получать доступ.
Вы организуете код в трёх файлах:
Device.php: создайте классDevice, представляющий электронные устройства с разными уровнями конфиденциальности данных. Добавьте:- свойство
public$brandдля названия производителя; - свойство
protected$modelNumberдля внутренней идентификации; - свойство
private$manufacturingCodeдля данных, предназначенных только для фабрики.
privategetManufacturingCode(), который возвращает manufacturing code. Добавьте методpublicgetModelInfo(), который возвращает"Model: [modelNumber]". Наконец, добавьте методpublicgetFullCode(), который возвращает"[brand]-[manufacturingCode]". Это демонстрирует, как сам класс может получать доступ к собственным private-членам.- свойство
Smartphone.php: создайте классSmartphone, который расширяетDevice. Подключите файл Device. Конструктор должен принимать brand, modelNumber, manufacturingCode и название operating системы. Вызовите конструктор parent с первыми тремя значениями, затем сохраните OS в private свойстве. Добавьте public методgetDeviceDetails(), который возвращает"[brand] [modelNumber] running [os]". Обратите внимание: вы можете напрямую обращаться к public$brandи protected$modelNumber, но не можете напрямую обращаться к private$manufacturingCode: вместо этого нужно использовать inherited public методgetFullCode().main.php: подключите файл Smartphone. Вы получите четыре inputs: brand, modelNumber, manufacturingCode и operating систему. Создайте instanceSmartphoneс этими значениями. Print три строки:- результат вызова
getDeviceDetails(); - результат вызова inherited метода
getModelInfo(); - результат вызова inherited метода
getFullCode().
- результат вызова
Эта задача подчёркивает ключевое различие: ваш класс Smartphone может свободно использовать protected $modelNumber, inherited от Device, но private $manufacturingCode и getManufacturingCode() остаются полностью скрытыми: доступ к ним возможен только через public interface, который Device решит предоставить.
Попробуйте сами
<?php
require_once 'Smartphone.php';
// Читать входные данные
$brand = trim(fgets(STDIN));
$modelNumber = trim(fgets(STDIN));
$manufacturingCode = trim(fgets(STDIN));
$os = trim(fgets(STDIN));
// TODO: Создайте экземпляр Smartphone с входными значениями
// TODO: Выведите результат getDeviceDetails()
// TODO: Выведите результат унаследованного метода getModelInfo()
// TODO: Выведите результат унаследованного метода getFullCode()
?>В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
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