2015-05-03 24 views
0

自從幾天以來,我一直在尋找這個,但沒有找到解決方案。在不修改構造函數的情況下更改由父類設置的變量

這裏是我的代碼:

// Main class 
class My_Parent { 

    private $foo = ''; 

    // The constructor is set. Now all extended classes will get it. 
    function __construct() { 
     var_dump($foo); 
    } 

    function set_val($value) { 
     $this->foo = $value; 
    } 

} 

// Extended class 
class My_Child extends My_Parent { 

    // Here's the problem. I've modified the constructor 
    function __construct() { 
     parent::set_val('bar'); 
     parent::__construct(); // I don't want to call the parent costructor again 
    } 

} 

new My_Child(); 

這只是正常工作,但沒有如我所料。我不想修改構造函數,所以我需要再次從父級調用它。看起來很奇怪。我將爲我的項目制定一個可擴展的框架。所以,這件事很煩人。

我想是這樣的:

class My_Child extends My_Parent { 

    // Just set the value somehow. do not modify the constructor 
    $this::set_val('bar'); 

} 

new My_Child(); 

這樣,我不必再調用構造函數。但上面的代碼會引發語法錯誤。

對此有何期待?

回答

0

剛發現一個棘手的解決方案。

首先,我設置了一個空函數,並在父類的構造函數中調用它。然後我在擴展類中通過該函數修改了變量。代碼如下所示:

// Main class 
class My_Parent { 

    private $foo = ''; 

    // The constructor is set. Now all extended classes will get it. 
    function __construct() { 

     // We open the portal so that the value can change 
     $this->portal(); 

     // Then we use the value as we want 
     var_dump($foo); 

    } 

    function set_val($value) { 
     $this->foo = $value; 
    } 

    // This function will play the role of constructor of extended classes 
    function portal() { 
    } 

} 

// Extended class 
class My_Child extends My_Parent { 

    // We just use portal to set the value. Constructor is still untouched! 
    function portal() { 
     parent::set_val('bar'); 
    } 

} 

new My_Child(); 

這是按我想要的完美工作的。一切都在評論中解釋。

0

也許你在想這個。如果你想初始化一個恆定值的屬性,你可以簡單地把它聲明保護並在子類中重寫它:

class MyParent { 
    protected $foo = 'bar'; 

    // ... 

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

class MyChild extends MyParent { 
    protected $foo = 'baz'; 
} 

echo (new MyParent())->getFoo(); // "bar" 
echo (new MyChild())->getFoo(); // "baz" 
+0

是的,可以做的工作,但我試圖保持私有變量。正如我在我的問題中提到的那樣,它正在構建一個框架。所以,如果我將變量聲明爲受保護的,我可能會發生衝突。 –

+0

@SohanZaman原則上這是一個有效的論證;然而,在你的回答中,你只能將問題轉移到另一個地方。現在,您可以使用兩個(在您的情況下甚至是公共!)函數,而這些函數可以被兒童類覆蓋,並帶來很多副作用。 – helmbert

相關問題