<?phpclass pa{ private function m(){ echo 'Parent\'s function'; } public function run(){ $this->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调用的方法要么是 父类的方法,要么是 父类中被子类重写的。
你的子类实例中没有定义run方法,访问的就是父类的公共方法run,此时$this应该已经是指向父类了,所以$this->m()调用的就是父类中未被重写的私有m方法
B = { (继承自Class A)
比如下面这里例子
<?phpclass pa{ public function a(){ $this->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()
第一种请看等价于:
<?phpclass child{ private function m(){ echo 'Parent\'s function'; } public function run(){ $this->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情况下不同,谢谢
最后回复一帖,不想在这个问题多做纠结了
首先,看下面这个例子
<?phpclass pa{ private function m(){ echo 'Parent\'s function'; }}class child extends pa{ public function run(){ if(is_callable($this, 'm')) { echo 'private function can callable'; } else { echo 'private function can not callable'; } }}$obj=new child();if(method_exists($obj, 'm')) { echo 'private function can extends';} else { echo 'private function can not extends';}$obj->run();
接着再看
<?phpfunction print_method($obj) { $refObj = new ReflectionObject($obj); foreach($refObj->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 就是对象自己
应该是他本身吧!无论这个他是父类或子类、或者别的类?
?爆了~~~ 留名学习中~

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

PHP在現代化進程中仍然重要,因為它支持大量網站和應用,並通過框架適應開發需求。 1.PHP7提升了性能並引入了新功能。 2.現代框架如Laravel、Symfony和CodeIgniter簡化開發,提高代碼質量。 3.性能優化和最佳實踐進一步提升應用效率。

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

PHP類型提示提升代碼質量和可讀性。 1)標量類型提示:自PHP7.0起,允許在函數參數中指定基本數據類型,如int、float等。 2)返回類型提示:確保函數返回值類型的一致性。 3)聯合類型提示:自PHP8.0起,允許在函數參數或返回值中指定多個類型。 4)可空類型提示:允許包含null值,處理可能返回空值的函數。

PHP中使用clone關鍵字創建對象副本,並通過\_\_clone魔法方法定制克隆行為。 1.使用clone關鍵字進行淺拷貝,克隆對象的屬性但不克隆對象屬性內的對象。 2.通過\_\_clone方法可以深拷貝嵌套對象,避免淺拷貝問題。 3.注意避免克隆中的循環引用和性能問題,優化克隆操作以提高效率。

PHP適用於Web開發和內容管理系統,Python適合數據科學、機器學習和自動化腳本。 1.PHP在構建快速、可擴展的網站和應用程序方面表現出色,常用於WordPress等CMS。 2.Python在數據科學和機器學習領域表現卓越,擁有豐富的庫如NumPy和TensorFlow。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

Atom編輯器mac版下載
最受歡迎的的開源編輯器

Dreamweaver Mac版
視覺化網頁開發工具