为每个父母的班级孩子实例化一个实例?
Posted
技术标签:
【中文标题】为每个父母的班级孩子实例化一个实例?【英文标题】:Instantiating one instance each of parent's class children? 【发布时间】:2017-08-02 02:46:23 【问题描述】:为了测试我的东西,我想为我命名的父类的每个子类自动实例化一个实例,而无需手动调用类名(太多了)。
例如:
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)。
感谢您的建议,
【问题讨论】:
您可以使用get_declared_classes()
和ReflectionClass::getParentClass()
来查找扩展某个类的类(假设所有包含子类的文件都已加载)但这会使您的代码更难阅读和理解.只列出子类要清楚得多。您可以使用一些简单的 shell 脚本(grep
、sed
/cut
等)从代码中提取子类列表。
这违背了测试的想法。您可以继承和覆盖函数,因为每个子类的行为与其父类不同。您必须对它们进行测试。
【参考方案1】:
这在实际情况下并不是很有用,但使用@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。
【讨论】:
以上是关于为每个父母的班级孩子实例化一个实例?的主要内容,如果未能解决你的问题,请参考以下文章