2011-07-27 94 views
6

我正在嘗試做一些我認爲很簡單的事情,但由於我在PHP中使用OOP相對較新,所以我遇到了一些麻煩。更改子類的受保護變量的值

這裏是我的代碼:

<?php 
class MyClass 
{ 
    protected $variable = 'DEFAULT'; 

    function __construct($newVariable) 
    { 
     $this->variable = $newVariable; 
     echo $this->variable; 
    } 
} 
class OtherClass extends MyClass 
{ 
    function __construct() 
    { 
     echo $this->variable; 
    } 
} 

$foo = new MyClass('MODIFIED'); // Output : MODIFIED 
$bar = new OtherClass(); // Output : DEFAULT 
?> 

我搜索了很多不同的線程和網站,但還沒有找到我怎麼能$變量的重新定義價值可能傳遞到子類。 有人可以指導我通過它嗎?如果有辦法。

在此先感謝。

編輯明確什麼是我有這個問題的腳本實際發生的情況: 我有一個創建一個表單,並在班上有幾個變量,告訴功能我們是什麼環境在一類:如果這是一種多語言形式或不是,如果我想要一個簡單的形式或結構化的,這樣的參數。 其中一些環境變量是通過執行類的功能來修改的。

現在,由於我的頁面需要,我有一個專門用於創建「選擇」字段的子類。它繼承了主類的核心功能來創建字段等,但子類需要多個參數。 事情是,我仍然希望選擇類繼承主類中的環境參數,處於它們所處的狀態。

當我打字時,我意識到我接近它的方式可能不是正確的方式,因爲當我查看我的代碼時,我認爲可能有另一種方法來做到這一點。在我的代碼中,我有兩個對象,我只需要它就是一個,但我真的不知道我會如何實際執行。

+1

你不重新定義變量,你只是將它設置在父母的構造函數。稱它爲你所需要的。 – hakre

+0

這裏的OOP只是函數的繼承和它們的默認變量。這不是神奇地將兩個物體連接在一起。可悲的是。 –

回答

2

你不重新定義變量,你只是將它設置在父項構造函數中。調用它,並且你已經得到了你所需要的(見代碼中的註釋,這只是一行):

<?php 
class MyClass 
{ 
    protected $variable = 'DEFAULT'; 

    function __construct($newVariable) 
    { 
     $this->variable = $newVariable; 
     echo $this->variable; 
    } 
} 
class OtherClass extends MyClass 
{ 
    function __construct() 
    { 
     parent::__construct(); # <<--- do this 
     echo $this->variable; 
    } 
} 

$foo = new MyClass('MODIFIED'); // Output : MODIFIED 
$bar = new OtherClass(); // Output : MODIFIED 
?> 

即使你有兩個類的定義,具體實例將永遠是一個班的。一個類可以繼承父類,但是如果您重寫方法(就像您使用構造函數一樣),父類方法將不會被稱爲,因爲它已被覆蓋。但是,使用parent關鍵字,您可以從孩子內部訪問父母的方法。

+0

嗯,問題是,我在這裏感興趣的是'MODIFIED'值。如果我再次調用parent :: _構造,我將需要指定$ newVariable。因此,無論我放什麼,它都不會是第一次傳遞給MyClass的價值。 總的來說,我有一大堆的,我需要傳遞給孩子上課,這有時被MyClass的內部功能修改的變量變數,但我開始懷疑它實際上是可能的。 –

+0

@Maxime:這只是繼承。受保護的成員可以由父母和子女訪問,但它始終是同一個變量,所以無論子代碼或父代碼如何更改,都會訪問相同的變量。你必須告訴更多你實際想要達到的目標,因爲你評論過的我無法看到你的問題。有很多方法可以處理繼承,所以更好地告訴你想實現什麼。重新定義你創造它不會發生。 – hakre

+0

在這裏,我在主文章中添加了上下文,但所有這些答案都指出,我可能只是採取了錯誤的方法來完成我想要做的事情。 –

1

MyClass的構造函數在OtherClass中被覆蓋。父構造函數不是隱式自動運行。如果您還想運行父構造函數,請撥打OtherClass::__construct中的parent::__construct()

您當然會遇到問題,因爲MyClass::__construct需要一個參數,而OtherClass::__construct沒有。像這樣,你如何期待價值改變......?

0

您需要調用在子類中添加parent

function __construct() 
{ 
    parent::__construct(); 
    echo $this->variable; 
} 

你可以做到這一點與任何功能:

function doSomethingAWESOME() 
{ 
    parent::doSomethingAWESOME(); 
    echo "I think that was awesome"; 
} 

,基本上,語句達,「你知道嗎在我將它覆蓋之前,你要在父類中做什麼?是的,在這裏做。「

也很酷:

function doSomethingAWESOME() 
{ 
    echo "NEVER!!!"; 
} 

function parentSomethingAwesome() 
{ 
    // calls the parent class's definition of some doSomethingAWESOME 
    parent::doSomethingAWESOME(); 
} 
1

子類既繼承方法和默認變量。如果你開始一個新的實例不繼承根類的屬性,因爲$foo$bar是兩個不同的對象

您必須執行$bar = new OtherClass("MODIFIED");,然後再將parent::__construct($newVariable)添加到第二個__construct。 (以及相應的參數)

基本上,你不能指望一個新實例(這是平行於$ foo的一個),「神奇地」繼承修改一個從原來的$ foo的。你必須找到一個方法來傳遞它(因此,調用父構造函數)。

0

你想要做什麼是不可能的,因爲-是:$ foo和$酒吧是您的類的實例,以便它們之間有沒有聯繫。

要使用建設比喻,你的兩個類是像建設計劃:房子的計劃,和一所房子的一個車庫的計劃。你想要做的就像你建造一所房子(例如一個班),在其中放置某種牀(設置一些變量),並且當你用車庫建造另一間房子時,你想要一張牀。這不會發生。