2011-04-27 65 views
1

请告知这里发生了什么?PHP OOP:属性/方法的范围

我们有以下类一起工作:

  • 一个抽象基类的形式元素“
  • 一个抽象的“容器”类 延伸形式元素类和 基团形成元件
  • “字段”类扩展了 容器

在“字段”类中,我们称之为“我”从名为'setErrors($ vars)'的'表单元素'类中设置一个名为'hasErrors'的属性。 $ vars携带一个布尔值。

在'表单元素'类中有另一个名为'hasErrors()'的方法,我们尝试在'field'类中调用以测试先前设置的布尔值的结果,但它返回false。

最初声明为false的hasErrors属性未被覆盖?

表单元素class(基)

private $hasErrors = false; 

public function setErrors($flag) 
{ 
... 
$this->hasErrors = $flag; 
... 
} 

public function hasErrors() 
{ 
return $this->hasErrors; 
} 

Field类

public function validate($value) 
{ 
... 
$this->setErrors($foundErrors);//$foundErrors only local to this method 
... 
} 

public function getField() 
{ 
... 
    if($this->hasErrors()) 
    { 
    //do something... 
    } 
... 
} 

为什么财产 'hasErrors' 没有被覆盖?这对于不同类之间的继承范围有什么关系?

不知道这是如何工作,但在此先感谢。

+0

我觉得这也许迷惑人通过相同的名字。 'field'类中的$ hasErrors变量仅对'validate'方法是本地的。它只是作为'setErrors'方法中的一个参数传递。也许我应该编辑代码以显示$ isErrors? – 2011-04-27 13:13:22

+0

这应该起作用。在'validate'中,你使用public setter方法'setErrors'设置值。这是完全合法的。但是if($ this-> hasErrors())位于哪里呢?如果我把它放在'validate'方法中(你有它在某个地方),它会正常工作,因为它应该。哎呀,没关系。我忽略了你也有一个容器类('class field extends container extends formelement')。 – 2011-04-27 13:18:56

+0

对不起,我编辑了代码以显示'hasErrors()'方法是如何被调用的,并且在'validate()'方法中更改了局部变量名称,因为这很混乱。 $ foundErrors(已重命名)布尔变量被传递给'setErrors()'方法。这与基类中的$ hasErrors属性不同。 – 2011-04-27 13:36:39

回答

0

我很抱歉不能直接回答你的问题,但其他答案是误导性的,我觉得我必须介入一点。尤其是因为类似的测试代码工作正常

您是否尝试将代码剥离到基础?正如一个测试,我创建了正常工作的情况如下:

<?php 
class test { 
     private $var = 'unset'; 
     public function setVar($val) { 
       $this->var = $val; 
     } 
     public function getVar() { 
       return $this->var; 
     } 
} 
class another extends test { 
     public function __construct() { 
       echo $this->getVar() . "\n"; 
       $this->setVar('set'); 
       echo $this->getVar() . "\n"; 
     } 
} 
class third extends another { 
     public function __construct() { 
       parent::__construct(); // This will output 'unset\nset\n' 
       $this->setVar('set second'); 
       echo $this->getVar() . "\n"; 
     } 
} 
$a = new third(); 

输出:

> php tmp.php 
unset 
set 
set second 

更新为根据注释,相同的输出:

class another extends test { 
     public function methodAnother() { 
       echo $this->getVar() . "\n"; 
       $this->setVar('set'); 
       echo $this->getVar() . "\n"; 
     } 
} 
class third extends another { 
     public function methodThird() { 
       $this->setVar('set second'); 
       echo $this->getVar() . "\n"; 
     } 
} 
$a = new third(); 
$a->methodAnother(); 
$a->methodThird(); 
+0

我认为这可以回答所有问题,但我不像你们中的一些人那么快,所以会让你知道,欢呼。 – 2011-04-27 13:40:22

+0

非常感谢Rudi,你的分析问题的方法的确非常好。如果你在'field'类的构造函数中调用'setErrors()'方法,就像你的例子(第三个),但不能像我们的代码中那样从类中的其他任何地方调用。如果这个答案很简单,请你解释一下为什么?将不胜感激。 – 2011-04-27 14:43:45

+0

嗨史蒂夫,抱歉,但应该仍然工作正常,我修改'另一个'和'第三'有另一个方法,每个构造函数的代码。请参阅我的答案的扩展名(对不起,它有点长)。 – 2011-04-27 14:49:54

2

您必须声明$hasErrors作为受保护的属性不是私有的。

私有方法不会被继承。

+0

感谢您的快速响应,但在这种情况下,这肯定无关紧要,因为我们将基础类中的属性设置为公共方法,并在子类中获取结果。无论如何我都改变了它,但它没有帮助。 – 2011-04-27 12:50:13

+0

是的,但是当你调用setError方法时,它试图设置子类属性不是基地。 – Headshota 2011-04-27 13:01:28

+0

这不是事实,它会让他们很好。 – 2011-04-27 13:22:57