Языки программирования

Наследование классов в PHP

Наследование — это не просто создание точной копии класса, а расширение уже существующего класса, чтобы потомок мог выполнять какие-нибудь новые, характерные только ему функции.
Наследование — это хорошо зарекомендовавший себя принцип программирования. 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 закончен. Думаю все понятно, но если есть вопросы задавайте их комментариях. Всем удачи!
Самоучитель по PHP