PHP子类不会覆盖新值

I am very new to OOP and trying to figure it out. I have the following code for a Mammal class which I plan to develop further. I have a child class Bear that echoes the correct values, but I can't over-write the $name, $move, $ear, or $sound values in the subclass Grizzly.

abstract class Mammal
{
    protected $name;
    protected $limbs;
    protected $offspring = 'live';
    protected $move;
    protected $eat;
    protected $sound;

    protected function __construct($name, $limbs, $offspring, $move, $eat, $sound) {
        $this->name = $name;
        $this->limbs = $limbs;
        $this->offspring = $offspring;
        $this->move = $move;
        $this->eat = $eat;
        $this->sound = $sound;
    }

    public function getOutput() {
        echo "The {$this->name} has four {$this->limbs}. The offspring is birthed {$this->offspring} and move by {$this->move}. They eat {$this->eat} and talk by {$this->sound}.";
    }
}

class Bear extends Mammal
{
    public function __construct() {
        Mammal::__construct('bear', 'claws', $this->offspring, '', '', '');
    }
}

class Grizzly extends Bear
{
    public function __construct() {
        Bear::__construct('grizzly bear', 'claws', $this->offspring, 'lumbering', 'salmon', 'roaring');
    }
}

$grizzly = new Grizzly;
$grizzly->getOutput();

The output I am trying to get is: "The grizzly bear has four claws. The offspring is birthed live and move by lumbering. They eat salmon and talk by roaring." I appreciate any help!

The reason is that your bear class does not seem to take variables.


class Bear extends Mammal
{
    public function __construct() { //See, this constructor takes nothing
        Mammal::__construct('bear', 'claws', $this->offspring, '', '', '');
    }
}

Here is what I did to make it work



class Bear extends Mammal
{
    public function __construct($bear = 'bear') {//right hear
        Mammal::__construct($bear, 'claws', $this->offspring, '', '', '');
    }
}

Your code in codepad.org with my little change

Note: That's how I made it work

The problem is really in the design of Bear. You want your inheritance chain not to block the values you need. That said, you don't have to call the parent constructor…

class Grizzly extends Bear
{
    public function __construct() {
        Mammal::__construct('grizzly bear', 'claws', $this->offspring, 'lumbering', 'salmon', 'roaring');
    }
}

Skipping the parent constructor like I did here is not actually good OOP, but it works (and PHP's philosophy values pragmatism like this). In this case, though, you probably want to modify the Bear subclass to enable access to those properties.

class Bear extends Mammal
{
    public function __construct($type, $move, $eat, $sound) {
        parent::__construct($type . ' bear', 'claws', $this->offspring, $move, $eat, $sound);
    }
}

class Polar extends Bear
{
    public function __construct() {
        parent::__construct('polar', 'cross-country skiing', 'salmon', 'mewling');
    }
}

$polar = new Polar();
$polar->getOutput();

The polar bear has four claws. The offspring is birthed live and move by cross-country skiing. They eat salmon and talk by mewling.

My thoughts:

If you are creating species of animals then bear should abstract. You shouldn't be able to create a Bear, just like you can't create a Mammal.

Also a Bear and Grizzly bear have properties.

abstract class Bear extends Mammal
{
    protected $limbs = 'claws';
    protected $move = 'lumbering';
    protected $sound = 'roaring';
}

All bears have claws, lumber, and roar

class Grizzly extends Bear
{
    protected $name = 'Grizzly Bear';
    protected $eat = 'salmon';
}

A grizzly bear eats salmon

abstract class Mammal
{
    protected $name;
    protected $limbs;
    protected $offspring = 'live';
    protected $move;
    protected $eat;
    protected $sound;

    public function getOutput() {
        echo "The {$this->name} has four {$this->limbs}. The offspring is birthed {$this->offspring} and move by {$this->move}. They eat {$this->eat} and talk by {$this->sound}.";
    }
}

This would be my solution. Id get rid of a constructor all together.