Skip to content
Advertisement

What’s the way to bubble dynamic data through parent constructor?

Let’s say I have a farm with a variety of animals. When new animals arrive I want to welcome them. I don’t want to recreate the welcome function for every animal so I make 1 and extend it to the animal classes.

class Chicken
{
    public function __construct(ChickenCoop $chickenCoop)
    {
        $this->chickenCoop = $chickenCoop;
    }

    public function gate()
    {
        $this->chickenCoop->addChicken('Clara');
        $this->chickenCoop->addChicken('Paula');
        $this->chickenCoop->addChicken('Betty');
        echo $this->chickenCoop->welcomeAnimals();
    }
}

class ChickenCoop extends AnimalHousing
{
    private array $chickens = [];

    public function __construct()
    {
        parent::__construct($this->chickens);
    }

    public function addChicken(string $chicken)
    {
        $this->chickens[] = $chicken;
    }
}

class AnimalHousing
{
    private array $animals;

    public function __construct(array $animals)
    {
        $this->animals = $animals;
    }

    public function welcomeAnimals()
    {
        $body = "welcome ";

        foreach ($this->animals as $animal) {
            $body .= "{$animal} ,";
        }

        return $body;
    }
}

The problem is that parent::__construct($this->chickens); constructs an empty array to it’s parent. What is the way to pass this chicken data to the AnimalHousing class?

Advertisement

Answer

What you’re doing doesn’t make a great deal of sense really.

Why do you need an array of “chickens” separate from array of “animals” in the parent class? What is the point of the “animals” list in that case? It cannot be dynamically updated. And since $chickens is just a list of strings (not some more complex type specific to representing chickens), it doesn’t add any value over and above the $animals list.

It would make more sense for “addChicken” to add to the list of “animals” in the parent class, instead of a separate list in the child class.

Something like this, perhaps:

<?php
class Chicken
{
    public function __construct(ChickenCoop $chickenCoop)
    {
        $this->chickenCoop = $chickenCoop;
    }

    public function gate()
    {
        $this->chickenCoop->addChicken('Clara');
        $this->chickenCoop->addChicken('Paula');
        $this->chickenCoop->addChicken('Betty');
        echo $this->chickenCoop->welcomeAnimals();
    }
}

class ChickenCoop extends AnimalHousing
{
    public function __construct()
    {
        parent::__construct();
    }

    public function addChicken(string $chicken)
    {
        $this->animals[] = $chicken;
    }
}

class AnimalHousing
{
    protected $animals = [];

    public function __construct()
    {
    }

    public function welcomeAnimals()
    {
        $body = "welcome ";

        foreach ($this->animals as $animal) {
            $body .= "{$animal} ,";
        }

        return $body;
    }
}

$coop = new ChickenCoop();
$chick = new Chicken($coop);
$chick->gate();

Demo: http://sandbox.onlinephpfunctions.com/code/37c101fc4861dacf64c417e3213869e20e6847a1

(Techinically at the moment, having a “ChickenCoop” subclass doesn’t really add any value at all, since you could just have an “addAnimal” function in the parent class and create an instance of AnimalHousing instead. But I assume you maybe intend to add more chicken-specific functionality to the class in future, so for that reason I won’t recommend removing it entirely.)

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement