>我对OOP有一个奇怪的情况
我的课程很简单
class Thing{
private
$children = array(),
$parent;
public function addChild(self $thing){
$this->children[] = $thing;
$thing->setParent($this);
}
public function setParent(self $thing){
$this->parent = $thing;
$thing->addChild($this);
}
}
$a = new Thing();
$b = new Thing();
$b->setParent($a);
如果我尝试使用这些函数,我会得到最大函数嵌套级别为 100 的错误,我知道为什么,但是我应该如何更改代码?现在的方式是有道理的,但是如果我删除任何函数调用,它将无法正常工作。
如注释中所述,您的代码在 setParent()
和 addChild()
之间创建了一个无限循环,其中对 setParent()
的调用隐式调用 setChild()
,而 又再次调用 setParent()
。
如果您希望代码正常工作,以便对setParent()
的调用或对addChild()
的调用强制执行两个对象中属性中的关系,则可以通过在addChild()
中添加if ()
条件来解决当前遇到的无限循环,仅当对象的父对象还不是当前对象($this
(时才调用setParent()
。
同样,您需要使用 in_array()
检查要添加为 addChild()
中的子对象是否尚未添加到父级的 $children
数组中。
class Thing{
private
$children = array(),
$parent;
// A name property just to see the results
public $name;
public function addChild(self $thing){
$this->children[] = $thing;
// Only set this object to the passed-in $thing object's
// $parent property if it has not already been set:
if ($thing->parent !== $this) {
$thing->setParent($this);
}
}
public function setParent(self $thing){
$this->parent = $thing;
// Only add the child via addChild() if it is not
// already in the array
if (!in_array($this, $thing->children)) {
$thing->addChild($this);
}
}
}
$a = new Thing();
$a->name = "THING A";
$b = new Thing();
$b->name = "THING B";
// Specify $a as the parent of $b
$b->setParent($a);
echo "'$a properties:'n";
print_r($a);
echo "'$b properties:'n";
print_r($b);
上面的输出是:
$a properties:
Thing Object
(
[children:Thing:private] => Array
(
[0] => Thing Object
(
[children:Thing:private] => Array
(
)
[parent:Thing:private] => Thing Object
*RECURSION*
[name] => THING B
)
)
[parent:Thing:private] =>
[name] => THING A
)
$b properties:
Thing Object
(
[children:Thing:private] => Array
(
)
[parent:Thing:private] => Thing Object
(
[children:Thing:private] => Array
(
[0] => Thing Object
*RECURSION*
)
[parent:Thing:private] =>
[name] => THING A
)
[name] => THING B
)
现在,使用反向操作,从 $a
和 $b
开始,然后将$b
作为子项添加到$a
,而不是将$a
添加为$b
的父项:
$a = new Thing();
$a->name = "THING A";
$b = new Thing();
$b->name = "THING B";
// Add $b as a child of $a
$a->addChild($b);
生成相同的输出:
$a properties:
Thing Object
(
[children:Thing:private] => Array
(
[0] => Thing Object
(
[children:Thing:private] => Array
(
)
[parent:Thing:private] => Thing Object
*RECURSION*
[name] => THING B
)
)
[parent:Thing:private] =>
[name] => THING A
)
$b properties:
Thing Object
(
[children:Thing:private] => Array
(
)
[parent:Thing:private] => Thing Object
(
[children:Thing:private] => Array
(
[0] => Thing Object
*RECURSION*
)
[parent:Thing:private] =>
[name] => THING A
)
[name] => THING B
)
(关于print_r()
输出中的"递归"的说明:这并不表示方法调用的行为是递归的,只是对象引用之间存在递归关系,这是您想要的。 $a
有一个子$b
,print_r()
尝试显示$b
的父级,这指向$a