@storm-coder

Не работает наследование. Где ошибка?

Пример по книге: "Таким образом, оба наших дочерних класса наследуют поведение общего родительского класса. И мы можем обращаться с объектом 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?
  • Вопрос задан
  • 136 просмотров
Решения вопроса 1
Так как у вас ShopProductWriter наследуется от ShopProduct, а там, в свою очередь, в конструкторе явно указано, что при создании объекта надо передать дополнительные параметры
function __construct ($title, $firstName, $mainName, $price, $numPages = 0, $playLength = 0)

То есть вызов должен быть таким
$writer = new ShopProductWriter("Wishmaster", "Группа", "Nightwish", "50 $", null, "70 min");
$product2 = new CDProduct ("Wishmaster", "Группа", "Nightwish", "50 $", null, "70 min");
$writer->write($product2);
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы