【问题标题】:PHP: call child constructor from static method in parentPHP:从父类中的静态方法调用子构造函数
【发布时间】:2011-03-24 10:07:52
【问题描述】:

我想在父类中有一个静态方法,它创建我调用此方法的任何子类的实例。

一个更清楚的例子:

班级家长{ 公共静态方法 make_objects($conditions){ 为了 (...){ // 这里我要创建一个实例 // 我正在调用 make_objects 的任何子类 // 基于某些 $conditions } } } 类子扩展父{ ... } $objects = sub::make_objects($some_conditions);

【问题讨论】:

  • 你没有错过extends吗?另外,我真的不明白你想做什么。你能举一个更有说服力的例子来说明make_objects 的返回值吗?
  • 是的,我缺少一个扩展。将有一个数据库,其中包含无数表示子类实例的条目,并且 make_objects 方法应该根据给定条件返回这些实例的某些子集。 basiccaly 我正在尝试创建类似 orm 工具的东西,但具有我项目所需的一些特定功能。

标签: php static constructor subclass


【解决方案1】:

从 php 5.3 开始,您可以为此使用 static 关键字

<?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);

打印

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

编辑:另一个(类似)示例

<?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";
}

打印

t=A
 A::__construct
  type of o=A
t=B
 B::__construct
  type of o=B
t=C
 C::__construct
  type of o=C

【讨论】:

  • 但据我了解,他想根据数据库中的类型创建实例。所以这对他也无济于事。
  • 也许,这个问题有点含糊。我们拭目以待。
  • 不,我想创建 sub 的实例,但要创建数据库中的行,所以它认为这是我希望的答案。现在去测试一下。
  • 测试了它,它正是我想要的,谢谢一百万。
  • 如果子构造函数是私有的怎么办?似乎不起作用。是否必须使用反射?
【解决方案2】:

我想你想要这样的东西:

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

class sub extends parent {

}

现在你可以像这样创建一个实例:

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

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

但是为什么要让所有子类都扩展父类呢?您不应该更愿意为您的模型(子类)创建一个父类,然后是一个工厂类,根据给定的条件创建此模型的实例吗?

【讨论】:

    【解决方案3】:

    嗯,那不就是:

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

    【讨论】:

    • 哦,我知道我忘记了示例代码中的扩展。但不是。 make 对象将变得相当长且复杂,并且将有几十个父类的子类,因此将整个方法放在每个子类中是非常不可取的(尽管它可能是唯一的选择)
    【解决方案4】:

    让父类成为抽象类,让父方法也成为抽象类

    abstract static class parent {
         abstract function make_method() {
             // your process
         }
    }
    
    class child extends parent {
         public function __construct() {
              parent::make_method();
         }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-25
      • 1970-01-01
      • 2016-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-16
      • 1970-01-01
      相关资源
      最近更新 更多