2011-04-27 44 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