Оглавление

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

Как в версии PHP 4, так и в PHP 5 объектно-ориентированное программирование построено на основе модели одиночного наследования. По определению, наследование — это возможность расширять возможности одного класса функциональностью другого класса. Когда один класс наследует другой, то все методы, свойства и константы родительского класса становятся доступными и из класса-наследника. Более того, классы-наследники могут также продолжать реализацию некоторых или всех методов, свойств и констант родительского класса, чтобы обеспечить дополнительные или отличающиеся функциональные возможности. Чтобы один класс мог наследовать другой класс, в его определении ставится ключевое слово extends. Рассмотрим пример, представленный в листинге 12.

 

class ParentClass {
    public $parentvar;
    public function parentOne() {
        echo "Called parentOne()\n";
    }
    private function parentTwo() {
        echo "Called parentTwo()!\n";
    }
}

class ChildClass extends ParentClass {
    public function childOne() {
        echo "Called childOne()!\n";
    }
    /* В определении метода parentOne() нет необходимости,
    так как он наследуется от класса ParentClass */
}

$v = new ChildClass();
$v->parentOne();

 

В этом примере определены два класса: ParentClass и ChildClass (который расширяет ParentClass). Каждый из них реализует свой собственный уникальный набор функций, однако поскольку класс ChildClass расширяет класс ParentClass, он включает все свойства и методы, к которым имеет доступ. Вот здесь и проявляются уровни доступа private, public и protected. При наследовании методов и свойств в классе-наследнике будут доступны только те члены класса, которые были объявлены как public или protected.

Примечание: Когда впервые упоминалось об уровнях public, private и protected, не было приведено детальное описание уровня protected. Как видите, причина кроется в том, что прежде чем приступать к рассмотрению уровня protected, необходимо познакомиться с наследованием. Если член класса объявляется как protected, то он будет доступен только в содержимом самого класса или любых его классов-наследников.

При рассмотрении наследования важно понять также то, как ограничиваются члены класса. Давайте посмотрим на код в листинге 13.

 

class ParentClass {
    public function callMe() {
        $this->anotherCall();
    }
    public function anotherCall() {
        echo "Вызван родительский класс!\n";
    }
}

class ChildClass extends ParentClass {
    public function anotherCall() {
        echo "Вызван дочерний класс!\n";
    }
}

$child = new ChildClass;
$child->callMe();

 

Что происходит при выполнении этого сценария? Вы уже знаете, что классы-наследники наследуют члены классов от родительских классов. А если класс-наследник тоже реализует этот член класса? В таких случаях, как при вызове метода callMe() в листинге 13, выполняемый метод можно найти в версии ChildClass. Принцип предпочтения “локального” члена класса является важной концепцией объектно-ориентированного программирования; в действительности, он относится также и к родительским классам. Давайте рассмотрим пример, представленный в листинге 14.


class ParentClass {
    public function callMe() {
        $this->anotherCall();
    }
    public function anotherCall() {
        echo "Вызван родительский класс!\n";
    }
}

class ChildClass extends ParentClass {
    public function anotherCall() {
        echo "Вызван дочерний класс!\n";
    }
}

$child = new ChildClass;
$child->callMe();

 

Что произойдет при вызове метода callMe()? Поскольку метод callMe() не определен в классе ChildClass, будет использоваться метод, определенный в родительском классе ParentClass. Если посмотреть на метод callMe() в классе ParentClass, то можно увидеть, что он вызывает еще один метод — anotherCall(). Хотя PHP выполняет метод callMe() из класса ParentClass, выполняться будет функция anotherCall() класса ChildClass, несмотря даже на то, что она существует в классе ParentClass. Это объясняется тем, что в PHP (а также и в большинстве других языков программирования, в которых поддерживается ООП), переменная $this всегда будет ссылаться на экземпляр класса, который производит вызов метода класса (в данном случае ChildClass), независимо от того, где находится соответствующий код.

Комментарии принадлежат их авторам. Мы не несем ответственности за их содержание.
Отправитель Нити