php中一個成員許可權困惑

來源:互聯網
上載者:User
問題:有如下代碼:
class Far
{
protected $arr;

protected function init() {
foreach ($this->arr as $k => $val) {
$this->$k = $val;
}
}

public function __construct() {
$this->init();
}

public function __set($name, $val) {
$this->$name = $val;
}
}

class Son extends Far
{
protected $a;

public function __construct() {
$this->arr = array(
'a' => '1',
);

parent::__construct();
}
}

$obj = new Son();
print_r($obj);
問:為什麼$obj輸出的結果中,a不是1,而是null.
Son Object
(
[a:protected] => 1
[arr:protected] => Array
(
[a] => 1
)

)

問題2:如果把上述代碼中,子類的private $a 改成protected $a 或public $a,則輸出:
Son Object
(
[a:protected] => 1
[arr:protected] => Array
(
[a] => 1
)

[bb] => 1
)

為什嗎?


回複討論(解決方案)

不明白你在說什嗎?
你列印的結果不是正確的嗎?

糾正一下,private時列印的結果如下:

Son Object(    [a:Son:private] =>     [arr:protected] => Array        (            [a] => 1        )    [bb] => 1)

son::a 是私人的,far:: init 訪問不到他

son::a 是私人的,far:: init 訪問不到他



不是有個__set魔術方法嗎?

__set 不是 far 的嗎?

__set 不是 far 的嗎?



子類不是繼承了它嗎?
$Son->bb = 1;
可以證明 Son得到了Far的__set

不錯,方法是繼承了,但許可權並沒有因繼承而改變

老婆是你的,並不能說你老子就能碰

不錯,方法是繼承了,但許可權並沒有因繼承而改變

老婆是你的,並不能說你老子就能碰


是的,那麼__set中的$this不是指向的當前執行個體對象,也就是Son的一個執行個體哦。而__set的作用就是可以用於訪問private或不存在的成員,

代?不完整啊,看了半天,都?看到有$bb。

代?不完整啊,看了半天,都?看到有$bb。


Sorry,$bb是我外部加的,如下:
$obj = new Son();$obj->bb = 1;print_r($obj);

private 是私人屬性,只能自己內部調用,執行個體都不可以調用。
當然Far不可以賦值,正常的。

private 是私人屬性,只能自己內部調用,執行個體都不可以調用。
當然Far不可以賦值,正常的。



呃,我的意思是,__set, __get方法其實就是用來訪問其中不存在或私人private的成員的方法。手冊中如下說明:
“在給不可訪問屬性賦值時,__set() 會被調用。”

參見:http://www.php.net/manual/zh/language.oop5.overloading.php

你的 __set 方法是定義在 Far 中的,所以他不能訪問 Son 的私人屬性
這樣寫就可以了

class Far {    protected $arr;    protected function init() {        foreach ($this->arr as $k => $val) {            $this->$k = $val;        }    }    public function __construct() {        $this->init();    }    public function __set($name, $val) {        $this->$name = $val;    }}class Son extends Far {    private $a;    public function __construct() {        $this->arr = array(            'a' => '1',        );        parent::__construct();    }    public function __set($name, $val) {        $this->$name = $val;    }}$obj = new Son();print_r($obj);
Son Object
(
[a:Son:private] => 1
[arr:protected] => Array
(
[a] => 1
)

)

你的 __set 方法是定義在 Far 中的,所以他不能訪問 Son 的私人屬性
這樣寫就可以了

class Far {    protected $arr;    protected function init() {        foreach ($this->arr as $k => $val) {            $this->$k = $val;        }    }    public function __construct() {        $this->init();    }    public function __set($name, $val) {        $this->$name = $val;    }}class Son extends Far {    private $a;    public function __construct() {        $this->arr = array(            'a' => '1',        );        parent::__construct();    }    public function __set($name, $val) {        $this->$name = $val;    }}$obj = new Son();print_r($obj);
Son Object
(
[a:Son:private] => 1
[arr:protected] => Array
(
[a] => 1
)

)



是的,我之所以寫在父類中,就是不想在每個子類中寫一個__set,按您所說的是沒有問題的。不過讓我不明白的是,即然它能從父類得到這個__set的方法。與寫在自己內部的__set方法,在操作成員時,倒底有什麼不同的。

私人的是不可侵犯的
仔細品味#7的第二句話

私人的是不可侵犯的
仔細品味#7的第二句話



有一點我不明白的是,如果我在__set列印當前$this,這裡我得到的是子類對象。那接著$this->name不就是子類對象的方法操作自己的成員嗎?為可這裡許可權卻沒有了。

要說多少遍你才能轉過彎來呢?
私人的屬性,只能被他所在類定義的方法訪問
請注意類和對象的區別

要說多少遍你才能轉過彎來呢?
私人的屬性,只能被他所在類定義的方法訪問
請注意類和對象的區別



如果你這樣說,我就能理解了。
  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.