每个父类的子级实例化一个实例?

时间:2017-03-11 21:12:58

标签: php class inheritance

为了测试我的东西,我想自动为每个父类的名字实例化一个实例,而不是手动调用类名(它太多了)。

例如:

Class Animal {
  public weight;
}

Class Dog extends Animal {
  public weight = 20;
}

Class SmallDog extends Dog {
  public weight = 18;
}

Class Cat extends Animal {
  public weight = 10;
}


function xy(){
  $classes = array();
  foreach parent->child as child(){
    $classes[] = new child()
  }
  //$classes = [Dog, SmallDog, Cat]
}

像(tm)这样的东西是否可行,如果是的话,怎么样?

作为进一步的信息,我有一个autoload_register来保存每个类,但它也包含我不想实例化的各种类。 另外,相对于上面的例子,我将Animal,Dog和Cat全部组装在一个文件中,我们称之为animal.php。

在上面的代码中,我将获得除Animal之外的任何实例,包括SmallDog。如果它不可能那样,我可以通过获取Dog和Cat并调用父亲为Dog的函数(以获得SmallDog实例化)。

感谢您的建议,

1 个答案:

答案 0 :(得分:0)

这在实际情况下并不实用,但使用@axiac注释可以实现ChildrenResolver类:

class ChildrenResolver
{ 
    protected $defaultClasses = [
        0 => 'stdClass',
        1 => 'Exception',
        2 => 'ErrorException',
        // ...
    ];

    protected $declaredClasses;

    public function __construct(array $declaredClasses = null)
    {
        if (is_null($declaredClasses)) {
            $declaredClasses = array_diff(
                get_declared_classes(),
                $this->defaultClasses
            );
        }

        $this->declaredClasses = $declaredClasses;
    }

    public function getChildClasses($class)
    {
        return array_filter(
            $this->declaredClasses,
            function ($declaredClassName) use ($class) {
                $declaredClass = new ReflectionClass($declaredClassName);

                while(($parent = $declaredClass->getParentClass())) {
                    if ($parent->name === $class) {
                        return true;
                    }

                    $declaredClass = $parent;
                }

                return false;
            }
        );
    }

    public function getDirectChildClasses($class)
    {
        return array_filter(
            $this->declaredClasses,
            function ($declaredClassName) use ($class) {
                $declaredClass = new ReflectionClass($declaredClassName);

                $parent = $declaredClass->getParentClass();

                return $parent ? $parent->name === $class : false;
            }
        );
    }
}

这个想法非常简单。我们遍历声明的类(通过get_declared_classes获得),使用ReflectionClass反映每个类,并比较我们从ReflectionClass::getParentClass得到的父与给定的父类。为了方便起见,我使用了array_filter函数。

有了这门课,你可以解决这样的孩子:

$childrenResolver = new ChildrenResolver;

var_dump($childrenResolver->getChildClasses('Animal'));
var_dump($childrenResolver->getDirectChildClasses('Animal'));
var_dump($childrenResolver->getChildClasses('Dog'));

这是working demo