問題:有如下代碼:
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不就是子類對象的方法操作自己的成員嗎?為可這裡許可權卻沒有了。
要說多少遍你才能轉過彎來呢?
私人的屬性,只能被他所在類定義的方法訪問
請注意類和對象的區別
要說多少遍你才能轉過彎來呢?
私人的屬性,只能被他所在類定義的方法訪問
請注意類和對象的區別
如果你這樣說,我就能理解了。