Пример по книге: "Поскольку свойство $price объявлено в классе ShopProduct , а не в BookProduct, попытка в приведенном выше коде (класс BookProduct" function getPrice () {return $this->price}) получить к нему доступ закончится неудачей. Чтобы решить эту проблему, нужно объявить свойство $price защищенным (p r o t e c t e d) и тем самым предоставить доступ к нему дочерним классам."
Свойство price вызывается из дочернего класса, которому предоставлен доступ к нему. Следуя логике инструкции - должно работать. Но нет! Где у меня ошибка?
<?php
class ShopProduct {
public $title;
public $producerMainName;
public $producerFirstName;
protected $price;
public $discount = 0;
function __construct ($title, $firstName, $mainName, $price, $discount) { // конструктор
$this -> title = $title; // через $this обращаюсь к свойству этого класса title и присваиваю ему значение (аргумент), которое прилетит в переменную $title, когда вызовется метод конструктора (вызывается при создании нового объекта)
$this -> producerFirstName = $firstName;
$this -> producerMainName = $mainName;
$this -> price = $price;
$this -> discount = $discount;
}
/*
Meтoд __construct ( ) вызывается, когда создается объект с помощью оператора new.
Значения всех перечисленных аргументов передаются конструктору.
Благодаря конструктору, создание экземпляров класса ShopProduct и определение значений их свойств выполняются в одном операторе.
*/
function getProducer () { // метод. возвр. имя и фам автора
return "{$this -> producerFirstName} " .
"{$this -> producerMainName}";
}
function getSummaryLine () { // метод возвращает название альбома (или книги); имя, фамилию автора
$base = "{$this -> title} ( {$this -> producerMainName}, ";
$base .= "{$this -> producerFirstName} )";
return $base;
}
function setDiscount ( $num ) { // метод. задать скидку
$this -> discount = $num;
}
function getPrice () { // метод, который принимает во внимание установленную скидку (=> цену и скидку)
return ($this -> price/* - $this -> discount*/);
}
}
/* Класс CDProduct (дочерний) расширяет возможности класса ShopProduct */
class CDProduct extends ShopProduct {
function __construct ($title, $firstName, $mainName, $price) {
parent:: __construct($title, $firstName, $mainName, $price); // Вызвать мeтoд __construct ( ) родительского класса
$this -> playLength = $playLength;
}
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 getNumberOfPages () { // метод. вернуть количество страниц этого ($this) класса
return $this -> numPages;
}
function getSummaryLine () { // метод. возвращает название книги; имя, фамилию автора и количество страниц
$base = "{$this -> title} ( {$this -> producerMainName}, ";
$base .= "{$this -> producerFirstName} )";
$base .= ": {$this -> numPages} стр.";
return $base;
}
function getPrice () {
return ($this -> price);
}
}
$product = new BookProduct ("Игра престолов", "Мартин", "Джордж", "20 $", "10");
echo $product -> price;