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.