Пример по книге: "Таким образом, оба наших дочерних класса наследуют поведение общего родительского класса. И мы можем обращаться с объектом BookProduct так, как будто это объект типа ShopProduct . Мы можем передать объект BookProduct или CDProduct методу w r i t e ( ) класса ShopProductWriter, и все будет работать как надо."
<?php
class ShopProduct {
public $numPages; // свойство.
public $playLength;
public $title;
public $producerMainName;
public $producerFirstName;
public $price;
function __construct ($title, $firstName, $mainName, $price, $numPages = 0, $playLength = 0) { // конструктор
$this -> title = $title; // через $this обращаюсь к свойству этого класса title и присваиваю ему значение (аргумент), которое прилетит в переменную $title, когда вызовется метод конструктора (вызывается при создании нового объекта)
$this -> producerFirstName = $firstName;
$this -> producerMainName = $mainName;
$this -> numPages = $numPages;
$this -> playLength = $playLength;
$this -> price = $price;
}
/*
Meтoд __construct ( ) вызывается, когда создается объект с помощью оператора new.
Значения всех перечисленных аргументов передаются конструктору.
Благодаря конструктору, создание экземпляров класса ShopProduct и определение значений их свойств выполняются в одном операторе.
*/
function getProducer () { // метод. возвр. имя и фам автора
return "{$this -> producerFirstName} " .
"{$this -> producerMainName}";
}
function getSummaryLine () { // метод возвращает название альбома (или книги); имя, фамилию автора
$base = "{$this -> title} ( {$this -> producerMainName}, ";
$base .= "{$this -> producerFirstName} )";
return $base;
}
}
/* Класс CDProduct (дочерний) расширяет возможности класса ShopProduct */
class CDProduct extends ShopProduct {
function getPlayLength() { // метод. возвращает время звучания
return $this -> playLength;
}
function getSummaryLine () { // метод. возвращает название альбома; имя, фамилию автора и время звучания
$base = "{$this -> title} ( {$this -> producerMainName}, ";
$base .= "{$this -> producerFirstName} )";
$base .= ": Время звучания - {$this -> playLength}";
return $base;
}
}
/* Класс BookProduct (дочерний) расширяет возможности класса ShopProduct */
class BookProduct extends ShopProduct {
function getSummaryLine () { // метод. возвращает название книги; имя, фамилию автора и количество страниц
$base = "{$this -> title} ( {$this -> producerMainName}, ";
$base .= "{$this -> producerFirstName} )";
$base .= ": {$this -> numPages} стр.";
return $base;
}
}
class ShopProductWriter extends ShopProduct {
public function write ($shopProduct) { // метод класса (ему передается обьект $product1 (уточнение, предназначен для работы с одним типом: ShopProduct) )
if (! ($shopProduct instanceof CDProduct) && ! ($shopProduct instanceof BookProduct) ) { // если переданный аргумент не относится к типу CDProduct и к типу BookProduct
die("Передан неверный тип данных");
}
$str = "{$shopProduct->title}: " // изменить значение свойства title аргумента прилетевшего в переменную $ShopProduct (не this а $shopProduct->title --- потому, что в методе есть параметр $shopProduct, который принимает прилетевший ему аргумент)
. $shopProduct -> getProducer()
." ({$shopProduct->price})\n ";
print $str;
}
}
$writer = new ShopProductWriter();
$product2 = new CDProduct ("Wishmaster", "Группа", "Nightwish", "50 $", null, "70 min");
$writer->write($product2);
Если не делать класс ShopProductWriter дочерним - все работает! Почему метод write() не работает в
дочернем классе ShopProductWriter?