Tutorial :Returning subclass of abstract class in abstract class method



Question:

I have a class which has a function to retrieve children elements from a database. The following code will be rather pseudo cause I want to keep it as easy as possible.

abstract class SomeHostObject extends SomeObject {       function getChild($identifier) {        global $database;        $id = $database->select('Some MySQL Query');        // that is the problem        return ?new? ???($id);     }    }  

As you see, the class SomeHostObject is abstract and has to be extended.

The thing is that the getChild() should not return a SomeHostObject instance (not only because it can't even be instantiated) but a new instance of the class that extends SomeHostObject.

For example, if there was a class PageObject which extends SomeHostObject, the function getChild() should return a new PageObject instance with the new id.

I don't know whether to call that question 'advanced' or not but to me it's a major problem.


Solution:1

abstract class SomeHostObject extends SomeObject {       function getChild($identifier) {        global $database;        $id = $database->select('Some MySQL Query');        // that is the problem        return $this->createObject($id);     }     abstract protected function createObject($id);    }    class PageObject extends SomeHostObject  {    protected function createObject($id)    {      return new PageObject($id);    }    }  


Solution:2

You could accomplish it with something as simple as this if the child object will be the same class as the object which calls getChild():

$class = get_class($this)    return new $class($id);  


Solution:3

Hm, if this is good software design or not is another discussion, more then 2 levels of inheritance smell a bit imho. You should think about using composition rather then inheritance. But to focus in the technical part of the question, I would use get_class in order to get the class name of the current instance and create a new one like so:

  <?php      class SomeObject    {}      abstract class SomeHostObject extends SomeObject {       function getChild($identifier) {          $className = get_class($this);          return new $className($identifier);       }    }      class PageObject extends SomeHostObject    {      private $identifier;        public function __construct($identifier = 0)      {        $this->identifier = $identifier;      }    }      $instance = new PageObject();    $child = $instance->getChild(10);      print_r($child);  

This prints on my machine something like

PageObject Object ( [identifier:private] => 10 )   

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »