Jump to content

[SOLVED] something similar to inheriting ...


friedemann_bach

Recommended Posts

Dear all,

 

I have a nice OOP issue here:

 

class God {
  public $name;
  private $creatures;
  
  public function God ($name) {
    $this->name = $name;
    $this->creatures = array();
    echo "$this->name is a great god.<br>";
  }
  public function CreateAnimal ($type) {
    $this->creatures = new Animal ($type,$this);
  }
}

class Animal {
  public $type;
  private $creator;
  
  public function Animal ($type,$creator) {
    $this->type = $type;
    $this->creator = $creator;
    echo "$creator->name has created a $this->type.<br>";
  }
}

$a = new God('Zeus');
$a->CreateAnimal('horse');
$a->CreateAnimal('jellyfish');

 

Output:

Zeus is a great god.
Zeus has created a horse.
Zeus has created a jellyfish.

 

What happens here:

There is a class named 'God' that contains an array 'creatures', and there is a second class named 'Animal'. The method God->CreateAnimal() can be used to create an instance of Animal in the God->creatures array. When an Animal is created, a reference to its creator (the corresponding God) is passed so that an Animal has a back reference to God.

 

My Questions for you:

(1) Is there an easier way to keep the back reference from 'Animal' to 'God'?

(2) If not so, is it more efficient to use "&$this" instead of "$this" or doen't make it a difference at all?

(3) From the stylistic point of view, is this good OOP? Or would you advise to use a different approach?

 

Thanks in advance for your comments!

 

Link to comment
https://forums.phpfreaks.com/topic/118762-solved-something-similar-to-inheriting/
Share on other sites

Re 2) It makes no difference. Objects are always passed by reference so the ampersand is completely redundant.

Re 1 and 3) See how I would do it below:

 

<?php
class God
{
private $name;
private $creatures = array();

public function __construct($name)
{
	$this->name = $name;

	echo $this->getName() . ' is a great god' . PHP_EOL;
}

public function getName()
{
	return $this->name;
}

public function addCreature(Animal $c)
{
	$this->creatures[] = $c;

	return $this;
}

public function getCreature(Animal $c)
{
	if (!in_array($c, $this->creatures)) {
		return false;
	}

	foreach ($this->creatures as $creature) {
		if ($c === $creature) {
			return $c;
		}
	}
}

public function getCreatures()
{
	return $this->creatures();
}
}

abstract class Animal
{
private $creator;
protected $name;

public function __construct(God $creator)
{
	$this->creator = $creator;

	echo $creator->getName() . ' creates a ' . strtolower($this->getName()) . PHP_EOL;
}

public function getName()
{
	if (empty($this->name)) {
		$name = get_class($this);
		$name = str_replace('Animal_', '', $name);

		return $name;
	}

	return $this->name;
}

public function getCreator()
{
	return $this->creator;
}

static public function create($type, God $creator)
{
	$class = 'Animal_' . ucwords($type);

	if (!class_exists($class)) {
		throw new Exception('Animal ' . $type . ' does not exist');
	}

	return new $class($creator);
}
}

class Animal_Horse extends Animal
{}

class Animal_Jellyfish extends Animal
{
protected $name = 'Jellyfish';
}

$god = new God('God');
$god->addCreature(Animal::create('horse', $god))
->addCreature(Animal::create('jellyfish', $god));
?>

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.