Отправляет email-рассылки с помощью сервиса Sendsay

PHP 5 для начинающих

  Все выпуски  

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


PHP 5 для начинающих

Программист, решая ту или иную задачу, может использовать готовый код (функцию, библиотеку, класс), если, конечно, этот код делает все так, как это необходимо. К сожалению, такая ситуация встречается крайне редко. Обычно приходится вносить в готовый код (если он вообще существует) какие-то изменения. Но измененная функция, библиотека или класс перестают быть самими собой; они существуют независимо от своей исходной версии. Если в оригинал будут внесены какие-то усовершенствования, это никак не отразится на производном от него коде. Синхронизация же всех существующих версий представляется весьма затруднительной. Таким образом, повторное использование кода в указанный способ оказывается не слишком эффективным.

Наследование представляет собой механизм повторного использования кода, не влияющий на исходную версию, но, в то же время, сохраняющей связь между ней и производным кодом. Таким образом, изменения, внесенные в исходную версию, отразятся и на производной.

Исходный класс, обладающий изначальными свойствами и поведением, называется базовым (base [9]), родительским (parent [8][9]) или суперклассом (superclass [9]). Производный (derived [9]) от него класс, наследующий свойства и поведение родительского класса, а также обладающий дополнительными и/или измененными свойствами и поведением, называется наследником (дословно - ребенком, дитем - child [8][9]) или субклассом (subclass [8][9]).

Наследование свойств и поведения родительского класса с последующим их частичным изменением и дополнением напоминает наследование генетического материала живыми организмами [9]. Однако, в отличие от биологических объектов (и некоторых языков программирования), в PHP у класса может быть не более одного непосредственного родителя[6].

В приведенном ранее примере (Пример 9.1, «Наследование») все свойства и методы родительского класса объявлены публичными, поэтому они доступны как из глобального контекста, так и из класса-наследника.

print $foobar->foo;
Foo
print $this->foo; // somewhere within class FooBar
Foo

Объявление свойства или метода защищенным предотвращает доступ к нему из глобального контекста, но сохраняет доступ из класса-наследника.

protected $foo = 'Foo'; // within class Foo
print $foobar->foo;
Notice:  Undefined variable: foo
Fatal error:  Cannot access empty property
        

Наконец, объявление свойства или метода приватным полностью предотвращает доступ к нему откуда-либо, кроме как из самого класса.

private $foo = 'Foo'; // within class Foo

Однако, в данном случае, все еще можно воспользоваться публичным методом getFoo(). Посколько этот метод остался публичным, доступ к нему сохранен. Сам же метод, будучи определен в классе Foo, имеет доступ к приватному свойству этого класса.

print $foobar->getFoo();
Foo
print $this->getFoo(); // somewhere within class FooBar
Foo

При необходимости класс-наследник может повторно определить свойство или метод родительского класса - это называется перекрытием (overriding).

Пример 9.2. Перекрытие

<?php

class Foo
{
    public $var;

    function __construct($var)
    {
        $this->var = $var; 1
    }

    public function getVar()
    {
        return $this->var;
    }

    public function someMethod()
    {
        print 'This method will be overridden.';
    }
}

?>
            
1

Неперекрытый конструктор родительского класса присваивает значение свойству текущего объекта. Если текущим является объект класса-наследника, то значение будет присвоено перекрытому свойству этого класса, а не оригинальному свойству родительского класса.

<?php

class Bar extends Foo
{
    public $var = 'Bar'; 1

    public function someMethod() 2
    {
        print 'This method has been overridden.';
    }
}

?>
            
1

Родительское свойство перекрывается в классе-наследнике.

2

Родительский метод перекрывается в классе-наследнике.

<?php

$foo = new Foo('Foo');
$bar = new Bar('Bar'); 1

print $foo->getVar();
print $bar->getVar(); 2

?>
            
FooBar
1

Неперекрытый конструктор родительского класса присваисвает значение свойству текущего объекта. Если текущим является объект класса-наследника, то значение будет присвоено перекрытому свойству этого класса, а не оригинальному свойству родительского класса.

2

Метод возвращает значение свойства в текущем объекте. Если текущим является объект класса-наследника, то будет возвращено значение перекрытого свойства.

<?php

$foo->someMethod();
$bar->someMethod();

?>
            
This method will be overridden.
This method has been overridden.
            

[Внимание]Внимание

При перекрытии в классе-наследнике конструктора следует иметь в виду, что PHP, в отличие от некоторых других языков, не поддерживает автоматического каскадного вызова родительских конструкторов. При необходимости следует делать это самостоятельно с помощью специальное выражение parent, ссылающееся на родительский класс.

    function __construct()
    {
        parent::__construct();
        /* ... */
    }
            


[6] Отсутствие поддержки множественного наследования компенсируется за счет возможности одновременного применения нескольких интерфейсов (см. Глава 10, Абстрактные классы и интерфейсы).

Created with DocBook


В избранное