2011-03-02 117 views
3

不知何故,我的思想遠離當前的問題,我犯了一個可怕的錯誤。 我在一個剛剛初始化類屬性的方法中調用了父構造函數..或者我..父構造函數工作是設置ID值。那麼PHP允許我這樣做。但是,這不正確?它看起來像我可以用同樣的方式調用類自己的構造函數。難道不應該只允許構造函數在創建類的實例時被調用...並且它們僅在創建實例時才被調用..調用方法內的構造函數

<?php 

    class A { 

     public function __construct() { 
      echo "Test<br />"; 
     } 

    } 

    class B extends A { 

     public function test() { 
      parent::__construct(); 
     } 

    } 

    $b = new B(); 
    $b->test(); 

    // OUTPUT: 
    // Test 
    // Test 

?> 

編輯:所以結論是,PHP允許你調用方法內的構造函數,但它實際上什麼都不做。另一個「TEST」字符串來自基類的構造函數。

+1

我敢肯定,會導致內爆(「,」,$ theInterwebs) – Detect 2011-03-02 21:49:15

+0

道德上,這是絕對錯誤的。只是不要這樣做。 – Detect 2011-03-02 21:49:56

+0

當你急着做東西,然後意識到發生的事情非常奇怪,這很有趣。 :) – PPPHP 2011-03-02 22:03:37

回答

3

一個詞完全描述了情況。

覆蓋

什麼情況是,當父母有這樣的方法爲__construct和子類中沒有該方法,當方法被調用子類中調用的父母方法。

例如:

class Parent 
{ 
    public function start(){} 
} 
class Child extends Parent 
{ 

} 

如果我叫子類中所涉及的起動方法,它執行Parent::Start(),但如果兒童類有一個叫做Start()方法是一個將被稱爲其重寫的父母版本。

每個類都有一個構造函數方法,php執行它來將該類編譯成一個對象,現在如果在類中有一個名爲__construct()的方法,PHP調用編譯該類的內部構造,然後調用您的覆蓋構造函數。

如果你沒有在子類PHP一個__construct方法執行父__construct

這就是爲什麼在你的對象初始化得到 X Test

您應該使用parent:__cosntruct()的唯一時間是如果您的Child類需要用戶定義的構造函數,則顯式調用父構造來準備父對象。

例如:

class Parent 
{ 
    public function __construct() 
    { 
     //Do work on Parent Class 
    } 
} 

class Child extends Parent 
{ 
    public function __construct() 
    { 
     //Do Work on Child Class 

     parent::__construct(); 
    } 
} 

你應該只調用過一個孩子的構造中和父類的構造不是一個孩子方法的原因是,構造函數應該永遠只被調用一次,這樣一來強制執行。

+0

哦,是的,這是正確的。 – PPPHP 2011-03-02 22:10:31

+1

如果PHP會以某種方式顯示錯誤或其他東西,它仍然會很好。 – PPPHP 2011-03-02 22:11:42

+0

你是絕對正確的。那麼現在我儘量不要失去焦點。 :)不知何故,我在這個層面上,即使是像這些最簡單最基本的東西,我也會質疑。不知何故,我需要有人向我說出什麼是對的,什麼是錯的。 – PPPHP 2011-03-02 22:27:12

1

您不會在任意時間調用父構造函數。您只能從子構造函數調用父構造函數,即在構造對象時。

如果php另有說明,那麼這僅僅是語言中如何實現類的一種人造物,而不應該被認爲是它永遠是件好事。

0

這不是一個好習慣,而良好的OOP語言通常不會讓你這樣做。如果你確切地知道你在做什麼,那完全沒問題。 (你可以記錄下來,所以其他使用該代碼的程序員理解你的概念)。

0

我會建議使用「init」方法來處理這種行爲。下面是一個例子:

class A { 
    public function __construct() { 
     $this->init(); 
    } 
    protected function init() { 
     echo "Test<br />"; 
    } 
} 

class B extends A { 
    public function __construct() { 
     // suppress parent constructor 
    } 
    public function test() { 
     $this->init(); 
    } 
}