74 Часть 1 1 . Объекты
Причина в том, что это свойство инициализируется как пустой массив в классе
Shop P roductWri t e r .
В РНР 4 работу абстрактных классов моделировали с помощью методов, которые
выводили предупреждающие сообщения или даже содержали операторы d i e ( ) . Это
заставляло программиста реализовывать абстрактные методы в производном клас
се, поскольку в противном случае сценарий переставал работать.
c l a s s Ab s t ractClass {
function abs t ractFunction ( ) (
d i e ( "Abst ractCl as s : : abs t r a c t Funct i on ( ) - абстрактная функция ! \ n " ) ;
П роблема в таком подходе состоит в том, что абстрактная природа базового
класса проверяется только в случае вызова абстрактного метода. В РНР5 абстракт
ные классы проверяются еще на этапе синтаксического анализа, что намного без
опаснее.
Интерфейсы
Как известно, в абстрактном классе допускается реализация некоторых методов,
не объявленных абстрактными. В отличие от них, интерфейсы - это чистой воды
шаблоны. С помощью интерфейса можно только определить функциональность,
но не реализовать ее. Для объявления интерфейса используется ключевое слово
i nt e r fa c e . В интерфейсе могут находиться только объявления методов, но не тела
этих методов.
Давайте определим интерфейс.
interf ace ChargeaЫe {
puЬl i c funct ion getPrice ( ) ;
Как видите, интерфейс очень похож на класс. В любом классе, поддерживающем
этот интерфейс, нужно реализовать все методы. определенные в интерфейсе; в про
тивном случае класс должен быть объявлен как абстрактный.
При реализации и нтерфейса в классе имя интерфейса указывается в объявле
нии этого класса после ключевого слова i mp l emen t s . После этого процесс реализа
ции интерфейса станет точно таким же, как расширение абстрактного класса, ко
торый содержит только абстрактные методы. Давайте сделаем так. чтобы в классе
S h op P roduct был реализован интерфейс C h a r g e a Ы e .
class ShopProduct implements ChargeaЫe );
// . . .
puЫ i c function getPrice ( )
return ( $this->price - $this ->discount
}
11
В классе S h op P roduct уже есть метод g e t P r i c e ( ) , что же может быть полезного в
реализации интерфейса Cha r g e a Ы e? И снова ответ связан с типами. Дело в том, что
реализующий класс принимает тип класса и интерфейса, который он расширяет.
Это означает, что класс C D P roduct относится к следующим типам.
CDProduct
ShopProduct
ChargeaЫe