Наследование — это не просто создание точной копии класса, а расширение уже существующего класса, чтобы потомок мог выполнять какие-нибудь новые, характерные только ему функции.
Наследование — это хорошо зарекомендовавший себя принцип программирования. PHP использует этот принцип в своей объектной модели. Этот принцип будет распространяться на то, каким образом множество классов и объектов относятся друг к другу.
Как происходит наследование
Наследование базируется на понятиях класс-родитель и класс-наследник. Используя определенный синтаксис, вы можете создать класс, который будет наследовать другой класс (становится его наследником).
Когда вы создаете дочерний класс, он наследует все поля и методы своего базового класса. В дочерний класс можно добавлять дополнительные поля и методы, тем самым расширяя функциональность класса-родителя.
Создание дочерних классов
Cоздать класс, который станет наследником другого класса, в PHP очень просто. Нужно только использовать ключевое слово extends:
class ParentClass {
// описание полей и методов
}
class ChildClass extends ParentClass {
// описание дополнительных полей и методов
}
Мы создали класс ParentClass, а затем класс ChildClass, который наследуется от ParentClass. ChildClass наследует все поля и методы класса ParentClass, и в него также могут быть добавлены свои поля и методы.
Пример наследования:
Пример наследования:
class Foo
{
public function printItem($string)
{
echo 'Foo: ' . $string . PHP_EOL;
}
public function printPHP()
{
echo 'PHP is great.' . PHP_EOL;
}
}
class Bar extends Foo
{
public function printItem($string)
{
echo 'Bar: ' . $string . PHP_EOL;
}
}
$foo = new Foo();
$bar = new Bar();
$foo->printItem('baz'); // Выведет: 'Foo: baz'
$foo->printPHP(); // Выведет: 'PHP is great'
$bar->printItem('baz'); // Выведет: 'Bar: baz'
$bar->printPHP(); // Выведет: 'PHP is great'
Перегрузка родительских методов
При создании дочернего класса, он наследует все поля и методы своего родительского класса. Но, может возникнуть необходимость изменить функциональность методов супер-класса в дочернем классе.
Чтобы перегрузить метод супер-класса в дочернем классе, просто создайте в нем метод с таким же названием. Тогда при вызове метода для объектов дочернего класса, будет вызываться именно перегруженный метод, а не метод супер-класса:
class ParentClass {
public function myMethod() {
// (действия)
}
}
class ChildClass extends ParentClass {
public function myMethod() {
// вызывется для объекта класса ChildClass
// вместо метода супер-класса MyMethod()
}
}
Переопределение методов
Если в классе-потомке определить метод с именем, которое уже использовалось при объявлении другого метода в классе-предке, то такой метод будет называться переопределённым. Такой подход вполне себя оправдывает ведь классы, стоящие в одной цепочки наследования, описывают схожие множества объектов со схожим поведением, и для обозначения похожего действий таких объектов вполне естественно использовать одно и то же имя метода.
Для примера возьмем два класса Admin и User. Например есть сайт где администратор, и пользователь могут авторизироваться, и для совершения этого действия можно использовать одно имя метода, например, authorize. Авторизация пользователя и администратора будет проходить немного по-разному: если для пользователя достаточно записать в сессию только логин, то для администратора необходимо записать в сессию ещё и уровень прав доступа.
class Admin {
private $rights;
public function __construct($login, $password, $rights) {
$this->login = $login;
$this->password = $password;
$this->rights = $rights;
}
public function authorize() {
$_SESSION['login'] = $this->getLogin();
$_SESSION['rights'] = $this->getRights();
}
public function getLogin() {
return $this->login;
}
public function getRights() {
return $this->rights;
}
public function setRights($rights) {
$this->rights = $rights;
}
}
class User {
private $login;
private $password;
private $rights;
public function __construct($login, $password, $rights = 0) {
$this->login = $login;
$this->password = $password;
$this->rights = $rights;
}
public function getLogin() {
return $this->login;
}
public function getRights() {
return $this->rights;
}
public function setRights($rights) {
$this->rights = $rights;
}
public function authorize() {
$_SESSION['login'] = $this->getLogin();
}
}
Теперь при написании кода, который будет авторизовывать пользователей или администраторов не нужно будет знать, от экземпляра какого класса вызывается метод authorize.
Обращение к полям и методам класса-предка
Иногда бывает необходимо получить доступ к полю или методу класса-предка из класса-наследника. Использование методов, реализованных в классе-предке, иногда позволяет избавиться от дублирования кода. Чтобы избежать дублирования можно вызвать конструктор класса-предка из конструктора класса-потомка.
Чтобы обратится к полям или методам класса-предка используется ключевое слово parent.
public function __construct($login, $password, $rights) {
parent::__construct($login, $password);
$this->rights = $rights;
}
Обращение к полям класса-предка происходит аналогичным образом:
class A {
public $property = 'value';
}
class B extends A{
public function getProperty() {
return $this->property;
}
}
$b = new B();
echo "{$b->getProperty()}
"; // value
На этом наш урок о наследовании в php закончен. Думаю все понятно, но если есть вопросы задавайте их комментариях. Всем удачи!