friedemann_bach Posted August 8, 2008 Share Posted August 8, 2008 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! Quote Link to comment https://forums.phpfreaks.com/topic/118762-solved-something-similar-to-inheriting/ Share on other sites More sharing options...
Daniel0 Posted August 8, 2008 Share Posted August 8, 2008 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)); ?> Quote Link to comment https://forums.phpfreaks.com/topic/118762-solved-something-similar-to-inheriting/#findComment-611490 Share on other sites More sharing options...
friedemann_bach Posted August 8, 2008 Author Share Posted August 8, 2008 Great. I am learning a lot from this. Many thanks, Daniel0! Quote Link to comment https://forums.phpfreaks.com/topic/118762-solved-something-similar-to-inheriting/#findComment-611494 Share on other sites More sharing options...
friedemann_bach Posted August 8, 2008 Author Share Posted August 8, 2008 I already marked the topic as 'solved', but any other approach is welcome. Quote Link to comment https://forums.phpfreaks.com/topic/118762-solved-something-similar-to-inheriting/#findComment-611495 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.