Модификатор доступа protected в ООП на PHP
Как вы уже знаете, приватные свойства и методы
не наследуются. Если вы хотите, чтобы метод
или свойство появились у потомка, вы должны
объявить их как public
. Проблема,
однако, в том, что публичные методы будут
также доступны и извне класса, а мы бы этого
не хотели.
Другими словами, мы хотели бы, чтобы некоторые методы или свойства родителя наследовались потомками, но при этом для всего остального мира вели себя как приватные.
Для решения этой проблемы существует специальный
модификатор protected
, который и реализует
описанное. Давайте изучим его работу на реальном
примере. Пусть у нас дан вот такой класс
User
с приватными свойствами name
и age
:
<?php
class User
{
private $name;
private $age;
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
public function getAge()
{
return $this->age;
}
public function setAge($age)
{
$this->age = $age;
}
}
?>
Пусть от класса User
наследует класс
Student
:
<?php
class Student extends User
{
private $course;
public function getCourse()
{
return $this->course;
}
public function setCourse($course)
{
$this->course = $course;
}
}
?>
Пока все отлично и все работает.
Пусть теперь мы решили в классе Student
сделать метод addOneYear
, который
будет добавлять 1
год к свойству age
.
Давайте реализуем указанный метод:
<?php
class Student extends User
{
private $course;
// Реализуем этот метод:
public function addOneYear()
{
$this->age++;
}
public function getCourse()
{
return $this->course;
}
public function setCourse($course)
{
$this->course = $course;
}
}
?>
Проблема в том, что если оставить свойство
age
приватным, то мы не сможем обратится
к нему в классе-потомке - это выдаст ошибку
при попытке вызова метода addOneYear
:
<?php
$student = new Student();
$student->setAge(25);
$student->addOneYear(); // выдаст ошибку
?>
Для исправления ошибки поправим класс User
- объявим свойство age
как protected
,
а не как private
:
<?php
class User
{
private $name;
protected $age; // объявим свойство как protected
...
}
?>
Теперь метод addOneYear
потомка сможет
менять свойство age
, но оно по-прежнему
не будет доступно извне наших классов. Проверим
работу класса Student
:
<?php
$student = new Student();
$student->setName('john'); // установим имя
$student->setCourse(3); // установим курс
$student->setAge(25); // установим возраст в 25
$student->addOneYear(); // увеличим возраст на единицу
echo $student->getAge(); // выведет 26
?>
Попытка обратится к свойству age
снаружи
класса выдаст ошибку, как нам и нужно:
<?php
$student = new Student();
$student->age = 30; // выдаст ошибку
?>
Скопируйте мой код класса User
. Самостоятельно
не подсматривая в мой код реализуйте описанный
класс Student
с методами getCourse
,
setCourse
и addOneYear
.