m(); }}class child extends pa{ public function m(){ echo 'child\'s function'; }}$obj=new child();$obj->run();
你們猜,結果是什麼,居然是parents function,可是,m()方法沒有被繼承因為protected,run()整合到了子類,那麼方法裡面的this應該指向子類執行個體,調用子類m方法,結果卻調用了,父類的m方法,如果把private改成public,則調用子類方法m,誰能解釋一下
回複討論(解決方案)
沒有找到更詳細的解釋extends作用機理的文章,以下只是我的猜測
我覺得造成這種問題的原因可能在於,雖然表面上是繼承了父類,但是父類實際上是存在的,也就是說,如果通過子類的執行個體化對象來調用父類中的某個方法,那麼實際上它進入到了父類的空間裡,那麼在父類空間裡的$this的作用範圍就是父類空間本身,而不能跨越到子類的空間中。
之所以會這麼猜想,是因為PHP的變數的引用原理,也就是當一個變數的值,是另一個變數的引用時,並不等同於這兩個變數變成了同一個變數,其實本身還是兩個變數,並且銷毀其中一個的時候,另一個仍然存在。
所以基於此我認為,子類的執行個體化對象不應該使用父類中的$this來代表子類的對象,這樣會造成對象的“越級”
還是那句話:私人的是不可侵犯的
樓上回複真心精闢啊!
沒有找到更詳細的解釋extends作用機理的文章,以下只是我的猜測
我覺得造成這種問題的原因可能在於,雖然表面上是繼承了父類,但是父類實際上是存在的,也就是說,如果通過子類的執行個體化對象來調用父類中的某個方法,那麼實際上它進入到了父類的空間裡,那麼在父類空間裡的$this的作用範圍就是父類空間本身,而不能跨越到子類的空間中。
之所以會這麼猜想,是因為PHP的變數的引用原理,也就是當一個變數的值,是另一個變數的引用時,並不等同於這兩個變數變成了同一個變數,其實本身還是兩個變數,並且銷毀其中一個的時候,另一個仍然存在。
所以基於此我認為,子類的執行個體化對象不應該使用父類中的$this來代表子類的對象,這樣會造成對象的“越級”
public 和 private結果是不一樣的,當屬性變為public,this就代表子類,能解釋嗎
如果父類是Class A,子類是Class B,個人覺得記憶體結構應該是這樣
A = Class A
B = { (繼承自Class A) Class B } <-- $this
子類對象建立的時候,應該是先建立了父類對象,然後父類的記憶體塊作為子類記憶體塊的一部分(子類=父類記憶體結構+子類自有)
所以父類中的定義的this調用的方法要麼是 父類的方法,要麼是 父類中被子類重寫的。
你的子類執行個體中沒有定義run方法,訪問的就是父類的公用方法run,此時$this應該已經是指向父類了,所以$this->m()調用的就是父類中未被重寫的私人m方法
B = { (繼承自Class A) <-- $this Class B }
比如下面這裡例子
sd(); // $this指向父類,而父類中未定義sd方法,子類的sd方法又是私人的,所以沒有輸出,子類的sd改成public即可輸出。 }}class child extends pa{ public function m(){ $this->a(); } private function sd(){ echo 'sd'; }}$obj=new child();$obj->m();
沒有深入理解過php的內部實現,歡迎指導討論。
還是那句話:私人的是不可侵犯的
沒明白,怎麼解釋public 和 private結果不同
private 私人的,只能被自己訪問。不會被繼承和覆蓋
public 共有的,可任意訪問、繼承、覆蓋
還是那句話:私人的是不可侵犯的
沒明白,怎麼解釋public 和 private結果不同
因為對於php來說 public 和 private 是2種不同的修飾
也就是說,當父類是private m時,子類的public m其實只是子類的內部方法,而和父類完全沒有關係,當調用run時,首先回去run聲明的空間尋找private的方法,如果找到,則直接執行,否則回去當前對象的空間尋找public或者protected的方法,如果還沒有找到,並且有extends class 則會去class的空間找,仍然沒有的話,則會報錯。
沒有找到更詳細的解釋extends作用機理的文章,以下只是我的猜測
我覺得造成這種問題的原因可能在於,雖然表面上是繼承了父類,但是父類實際上是存在的,也就是說,如果通過子類的執行個體化對象來調用父類中的某個方法,那麼實際上它進入到了父類的空間裡,那麼在父類空間裡的$this的作用範圍就是父類空間本身,而不能跨越到子類的空間中。
之所以會這麼猜想,是因為PHP的變數的引用原理,也就是當一個變數的值,是另一個變數的引用時,並不等同於這兩個變數變成了同一個變數,其實本身還是兩個變數,並且銷毀其中一個的時候,另一個仍然存在。
所以基於此我認為,子類的執行個體化對象不應該使用父類中的$this來代表子類的對象,這樣會造成對象的“越級”
public 和 private結果是不一樣的,當屬性變為public,this就代表子類,能解釋嗎
按照上面各位大大的解釋,private是不能被覆蓋的,而public可以被覆蓋,所以你改為public之後,就是父類的方法被子類覆蓋了
還是那句話:私人的是不可侵犯的
沒明白,怎麼解釋public 和 private結果不同
因為對於php來說 public 和 private 是2種不同的修飾
也就是說,當父類是private m時,子類的public m其實只是子類的內部方法,而和父類完全沒有關係,當調用run時,首先回去run聲明的空間尋找private的方法,如果找到,則直接執行,否則回去當前對象的空間尋找public或者protected的方法,如果還沒有找到,並且有extends class 則會去class的空間找,仍然沒有的話,則會報錯。
run()方法已經是子類的方法了,那麼$child->run()執行的就是子類自己的方法,run()裡面的this也是出現在子類中,指代子類對象,那麼$this->m()調用的因該是子類的m()而不是父類的m(),我這麼理解的。子類和父類的m()沒關係,這點我在文章中已經說了m()沒被繼承,我的問題是run()方法裡面的this指向,為什麼在private和public情況下不同,謝謝
private 私人的,只能被自己訪問。不會被繼承和覆蓋
public 共有的,可任意訪問、繼承、覆蓋
答非所問
沒有找到更詳細的解釋extends作用機理的文章,以下只是我的猜測
我覺得造成這種問題的原因可能在於,雖然表面上是繼承了父類,但是父類實際上是存在的,也就是說,如果通過子類的執行個體化對象來調用父類中的某個方法,那麼實際上它進入到了父類的空間裡,那麼在父類空間裡的$this的作用範圍就是父類空間本身,而不能跨越到子類的空間中。
之所以會這麼猜想,是因為PHP的變數的引用原理,也就是當一個變數的值,是另一個變數的引用時,並不等同於這兩個變數變成了同一個變數,其實本身還是兩個變數,並且銷毀其中一個的時候,另一個仍然存在。
所以基於此我認為,子類的執行個體化對象不應該使用父類中的$this來代表子類的對象,這樣會造成對象的“越級”
public 和 private結果是不一樣的,當屬性變為public,this就代表子類,能解釋嗎
按照上面各位大大的解釋,private是不能被覆蓋的,而public可以被覆蓋,所以你改為public之後,就是父類的方法被子類覆蓋了
那與this的指向有什麼關係?
還是那句話:私人的是不可侵犯的
沒明白,怎麼解釋public 和 private結果不同
因為對於php來說 public 和 private 是2種不同的修飾
也就是說,當父類是private m時,子類的public m其實只是子類的內部方法,而和父類完全沒有關係,當調用run時,首先回去run聲明的空間尋找private的方法,如果找到,則直接執行,否則回去當前對象的空間尋找public或者protected的方法,如果還沒有找到,並且有extends class 則會去class的空間找,仍然沒有的話,則會報錯。
run()方法已經是子類的方法了,那麼$child->run()執行的就是子類自己的方法,run()裡面的this也是出現在子類中,指代子類對象,那麼$this->m()調用的因該是子類的m()而不是父類的m(),我這麼理解的。子類和父類的m()沒關係,這點我在文章中已經說了m()沒被繼承,我的問題是run()方法裡面的this指向,為什麼在private和public情況下不同,謝謝
run()啥時候是子類方法了,你run是定義在父類裡的啊。它的public表示它可以被子類訪問和重寫,不代表它就直接屬於子類的方法啊。
$child->run()執行時$child執行個體裡是沒有run方法的。所以按照8樓所說,因為child是子類,所以在子類中找不到時到父類空間中找,這時父類中的run方法中的$this就是表示父類本身。
你使用$this->m()時,由於$this目前表示父類,而m()又是private的,所以不存在被覆蓋的可能,子類裡定義的是屬於子類自己的,跟父類無關。調用的就是父類的m,而不是子類。
當你把父類的m()的private改成public,父類的m()就存在被重寫的可能,所以程式會去繼承他的子類中去尋找(也就是你的$child),如果找到則調用子類的,沒找到調用父類自己的m()
第一種請看等價於:
m(); } public function m(){ echo 'child\'s function'; }}$obj=new child();$obj->run();
這樣搞也可以嗎?
搞錯了,請無視。竟然不能編輯。。
$this 是類執行個體化後的對象
所以 $this 指向的是對象,而不是類
執行個體化後,無論是基類還是繼承類的方法都在對象中
具體執行的是哪個方法由 php 根據規則決定
class pa{ private function m(){ echo __METHOD__ . ' Parent\'s function'; } public function run(){ echo __CLASS__ . ' '; $this->m(); }}class child extends pa{ public function m(){ echo __METHOD__ . ' child\'s function'; }}$obj=new child();$obj->run();得到 pa pa::m Parent's function
pa::m 方法是私人的,不可被覆蓋
class pa{ public function m(){ echo __METHOD__ . ' Parent\'s function'; } public function run(){ echo __CLASS__ . ' '; $this->m(); }}class child extends pa{ public function m(){ echo __METHOD__ . ' child\'s function'; }}$obj=new child();$obj->run();得到 pa child::m child's function
pa::m 方法是公有的,可以被覆蓋
class pa{ private function m(){ echo __METHOD__ . ' Parent\'s function'; } public function run(){ echo __CLASS__ . ' '; $this->m(); }}class child extends pa{ public function m(){ echo __METHOD__ . ' child\'s function'; } public function run(){ echo __CLASS__ . ' '; $this->m(); parent::run(); }}$obj=new child();$obj->run();得到
child child::m child's function
pa pa::m Parent's function
不能理解就慢慢理解吧。規矩不會因為你而改變
我就偏要再“答非所問”一回!
還是那句話:私人的是不可侵犯的
好精闢啊
還是那句話:私人的是不可侵犯的
沒明白,怎麼解釋public 和 private結果不同
因為對於php來說 public 和 private 是2種不同的修飾
也就是說,當父類是private m時,子類的public m其實只是子類的內部方法,而和父類完全沒有關係,當調用run時,首先回去run聲明的空間尋找private的方法,如果找到,則直接執行,否則回去當前對象的空間尋找public或者protected的方法,如果還沒有找到,並且有extends class 則會去class的空間找,仍然沒有的話,則會報錯。
run()方法已經是子類的方法了,那麼$child->run()執行的就是子類自己的方法,run()裡面的this也是出現在子類中,指代子類對象,那麼$this->m()調用的因該是子類的m()而不是父類的m(),我這麼理解的。子類和父類的m()沒關係,這點我在文章中已經說了m()沒被繼承,我的問題是run()方法裡面的this指向,為什麼在private和public情況下不同,謝謝
run()啥時候是子類方法了,你run是定義在父類裡的啊。它的public表示它可以被子類訪問和重寫,不代表它就直接屬於子類的方法啊。
$child->run()執行時$child執行個體裡是沒有run方法的。所以按照8樓所說,因為child是子類,所以在子類中找不到時到父類空間中找,這時父類中的run方法中的$this就是表示父類本身。
你使用$this->m()時,由於$this目前表示父類,而m()又是private的,所以不存在被覆蓋的可能,子類裡定義的是屬於子類自己的,跟父類無關。調用的就是父類的m,而不是子類。
當你把父類的m()的private改成public,父類的m()就存在被重寫的可能,所以程式會去繼承他的子類中去尋找(也就是你的$child),如果找到則調用子類的,沒找到調用父類自己的m()
這時父類中的run方法中的$this就是表示父類本身。按這麼說,你的理論就是,實力化子類的時候,父類也執行個體化了?this只能引用對象不能引用類,你的意思是建立子類的時候,順便把父類執行個體化了?否則this這個東西就是個矛盾,都不存在父類對象,哪存在this
$this 是執行個體化後的對象
就像 $obj=new child(); 後的 $obj 一樣
如果你是在對象內部訪問對象的方法和屬性的話,總不能老是要把 $obj 傳進去吧?
所以就有了 $this 這個載體
其實所有物件導向的語言中都有這個 this,也的確迷糊了眾多的初學者。其實沒有什麼好不理解的
this 就是對象自己
$this 是類執行個體化後的對象
所以 $this 指向的是對象,而不是類
執行個體化後,無論是基類還是繼承類的方法都在對象中
具體執行的是哪個方法由 php 根據規則決定
class pa{ private function m(){ echo __METHOD__ . ' Parent\'s function'; } public function run(){ echo __CLASS__ . ' '; $this->m(); }}class child extends pa{ public function m(){ echo __METHOD__ . ' child\'s function'; }}$obj=new child();$obj->run();得到 pa pa::m Parent's function
pa::m 方法是私人的,不可被覆蓋
class pa{ public function m(){ echo __METHOD__ . ' Parent\'s function'; } public function run(){ echo __CLASS__ . ' '; $this->m(); }}class child extends pa{ public function m(){ echo __METHOD__ . ' child\'s function'; }}$obj=new child();$obj->run();得到 pa child::m child's function
pa::m 方法是公有的,可以被覆蓋
class pa{ private function m(){ echo __METHOD__ . ' Parent\'s function'; } public function run(){ echo __CLASS__ . ' '; $this->m(); }}class child extends pa{ public function m(){ echo __METHOD__ . ' child\'s function'; } public function run(){ echo __CLASS__ . ' '; $this->m(); parent::run(); }}$obj=new child();$obj->run();得到
child child::m child's function
pa pa::m Parent's function
不能理解就慢慢理解吧。規矩不會因為你而改變
我就偏要再“答非所問”一回!
所以,版主的意思是,子類執行個體化前,父類也必須先執行個體化,否則存在在父類中的this沒有父類對象供引用,這是第一段代碼的結論。
但是根據第二段代碼,父類run裡面的this調用了子類對象的方法,所以結論,this指向子類,和第一段代碼矛盾
this到底指向父類還是子類對象
那麼,父類方法中的this,到底引用的是父類,還是子類對象?(難道存在父類對象),根據php代碼的運行結果,明顯矛盾,一會指向父類一會指向子類
$this 是執行個體化後的對象
就像 $obj=new child(); 後的 $obj 一樣
如果你是在對象內部訪問對象的方法和屬性的話,總不能老是要把 $obj 傳進去吧?
所以就有了 $this 這個載體
其實所有物件導向的語言中都有這個 this,也的確迷糊了眾多的初學者。其實沒有什麼好不理解的
this 就是對象自己
你說的這個我明白,我真正不明白的地方是,子類繼承父類方法function a()(這個方法a()內用到了this),這個繼承過來的this,到底是誰的this?13樓的回答看得出來他明白了我是什麼意思,但是解釋的有矛盾,而版主還是沒理解我的意思,我不是不明白private和this的規則,我市不知道在繼承過程中,this傳到了子類的過程中,指向發生了改變還是怎麼回事,你的前2個代碼的運行結果,明顯是php運行機制中的矛盾點
沒有什麼子類對象和分類對象
也不存在“子類執行個體化前,父類也必須先執行個體化”
執行個體化的只是一個類
只不過這個類可能包還有繼承過來的方法和屬性
再重複一遍:this 就是對象自己
既然這樣,那麼繼承過來的子類應該等同於下面把
class child extends pa{ public function m(){ echo 'child\'s function'; }public function run(){//只繼承了run(),m()私人,沒繼承 $this->m(); }}
那麼this就是指向這個類(child)的對象,可是他用了一個不存在的m()方法
還是那句話:私人的是不可侵犯的
沒明白,怎麼解釋public 和 private結果不同
因為對於php來說 public 和 private 是2種不同的修飾
也就是說,當父類是private m時,子類的public m其實只是子類的內部方法,而和父類完全沒有關係,當調用run時,首先回去run聲明的空間尋找private的方法,如果找到,則直接執行,否則回去當前對象的空間尋找public或者protected的方法,如果還沒有找到,並且有extends class 則會去class的空間找,仍然沒有的話,則會報錯。
run()方法已經是子類的方法了,那麼$child->run()執行的就是子類自己的方法,run()裡面的this也是出現在子類中,指代子類對象,那麼$this->m()調用的因該是子類的m()而不是父類的m(),我這麼理解的。子類和父類的m()沒關係,這點我在文章中已經說了m()沒被繼承,我的問題是run()方法裡面的this指向,為什麼在private和public情況下不同,謝謝
最後回複一帖,不想在這個問題多做糾結了
首先,看下面這個例子
run();
接著再看
getMethods() as $refFun) {echo "Define class name : ", $refFun->getDeclaringClass()->getName(), "\n";echo "Modifiers for method ", $refFun->name,":\n";echo $refFun->getModifiers() . "\n";echo implode(' ', Reflection::getModifierNames($refFun->getModifiers())) . "\n";}} class pa{ private function m(){ echo 'Parent\'s function'; } public function run(){ print_method($this);// 從上面的輸出可以看到,$this = $obj,// 這裡隱含一個輸出,為什麼會隱藏,這就是繼承的關係,我們知道public和protected會被子類同名給覆蓋// 但是private又會被保護,不能覆蓋,那麼其實就是有2份m,一個private m,另外一個就是子類 public m$this->m();// 而這裡的m調用時,會找那個m調用呢?// 很簡單,就是優先找當前method所定義class處的private,因為有了private就不用考慮繼承覆蓋的問題 }protected}class child extends pa{ public function m(){ echo 'child\'s function'; }}$obj=new child();print_method($obj);$obj->run();
但願你能明白。
貌似要你那麼做需要延遲靜態繫結
私人的無論是不是父類都不能調用
$this 是執行個體化後的對象
就像 $obj=new child(); 後的 $obj 一樣
如果你是在對象內部訪問對象的方法和屬性的話,總不能老是要把 $obj 傳進去吧?
所以就有了 $this 這個載體
其實所有物件導向的語言中都有這個 this,也的確迷糊了眾多的初學者。其實沒有什麼好不理解的
this 就是對象自己
應該是他本身吧!無論這個他是父類或子類、或者別的類?
?爆了~~~ 留名學習中~