@storm-coder

Почему возвращает ошибку при доступе к свойству родительского класса?

Пример по книге: "Поскольку свойство $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;
  • Вопрос задан
  • 122 просмотра
Решения вопроса 1
2 варианта:
1) (менее предпочтительно) Сделай поле $price публичным (public).
2) (более предпочтительно)В самом низу сделай "echo $product->getPrice();" вместо "echo $product->price;"

А вообще похоже на пример из какого-то устаревшего учебника по php.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@storm-coder Автор вопроса
2-е! Я понял ошибку. Тип protected доступен из основного класса и его подклассов, но не из внешнего кода. Хоть дочерний класс и наследует свойство price, из внешнего кода его вызвать нельзя. - Это идет в разрез с инструкцией в книге, немного запутанно.
Спасибо.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы