11

I want to have a static method in a parent class that creates instances of whatever subclass i call this method on.

An example to make this more clear:

class parent {
    public static method make_objects($conditions){
        for (...){
            // here i want to create an instance
            // of whatever subclass i am calling make_objects on
            // based on certain $conditions
        }
    }
}

class sub extends parent{
    ...
}

$objects = sub::make_objects($some_conditions);
martijnve
  • 993
  • 2
  • 9
  • 23
  • Aren't you missing an `extends`? Plus, I don't really understand what you want to do. Can you give a more telling example about what `make_objects` returns? – Pekka Aug 02 '10 at 20:40
  • Yes i am missing an extends. There is going to be a database with countless entries representing subclass instances and the make_objects method shoud return certain subsets of these instances based on given conditions. basiccaly im trying to create something like an orm tool but with some specific features i need for a project. – martijnve Aug 02 '10 at 20:51

4 Answers4

14

As of php 5.3 you can use the static keyword for this

<?php
class A {
  public static function newInstance() {
    $rv = new static();  
    return $rv;
  }
}
class B extends A { }
class C extends B { }

$o = A::newInstance(); var_dump($o);
$o = B::newInstance(); var_dump($o);
$o = C::newInstance(); var_dump($o);

prints

object(A)#1 (0) {
}
object(B)#2 (0) {
}
object(C)#1 (0) {
}

edit: another (similar) example

<?php
class A {
  public static function newInstance() {
    $rv = new static();  
    return $rv;
  }

  public function __construct() { echo " A::__construct\n"; }
}
class B extends A {
  public function __construct() { echo " B::__construct\n"; }
}
class C extends B {
  public function __construct() { echo " C::__construct\n"; }   
}

$types = array('A', 'B', 'C');
foreach( $types as $t ) {
  echo 't=', $t, "\n";
  $o = $t::newInstance();
  echo '  type of o=', get_class($o), "\n";
}

prints

t=A
 A::__construct
  type of o=A
t=B
 B::__construct
  type of o=B
t=C
 C::__construct
  type of o=C
VolkerK
  • 95,432
  • 20
  • 163
  • 226
1

I think you want something like this:

class parent {
  public static function make_object($conditionns) {
    if($conditions == "case1") {
      return new sub();
    }
  }
}

class sub extends parent {

}

Now you can create an instance like this:

$instance = parent::make_object("case1");

or

$instance = sub::make_object("case1");

But why would you want all the sub classes to extend the parent? Shouldn't you much rather have a parent for your models (sub classes) and then a factory class, that creates the instances for this models depending on the conditions given?

Sebastian Hoitz
  • 9,343
  • 13
  • 61
  • 77
0

Umm, wouldn't that be:

class sub extends parent {
  public static function make_objects($conditions) {
    //sub specific stuff here
    //....
  }
}
Eric B
  • 180
  • 4
  • oh i see i forgot the extends in my example code. but no. the make objects is goin to be quite long and compex and there are going to be dozens of subclasses of parent so putting the whole method in each subclass is highly undesirable (although it may turn out to be the only option) – martijnve Aug 02 '10 at 20:49
-1

make the parent class an abstract class and make the parent method also an abstract

abstract static class parent {
     abstract function make_method() {
         // your process
     }
}

class child extends parent {
     public function __construct() {
          parent::make_method();
     }
}
Ryan
  • 1