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);
2
  • 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? Commented Aug 2, 2010 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. Commented Aug 2, 2010 at 20:51

4 Answers 4

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
Sign up to request clarification or add additional context in comments.

6 Comments

But as I understand him he wants to create instances depending on the type he has in his database. So this would not help him either.
Maybe, the question is a bit vague. We'll see.
no i want to create instances of sub but for lines in my database so it hink this is the answer i was hoping for. Going to test it now.
Tested it and its just what i was looking for, thanks a million.
What if the child constructor is private? Doesn't seem to work. Would reflection have to be used?
|
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?

Comments

0

Umm, wouldn't that be:

class sub extends parent {
  public static function make_objects($conditions) {
    //sub specific stuff here
    //....
  }
}

1 Comment

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)
-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();
     }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.