<?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和Python各有优势,选择应基于项目需求。1.PHP适合web开发,语法简单,执行效率高。2.Python适用于数据科学和机器学习,语法简洁,库丰富。

PHP不是在消亡,而是在不断适应和进化。1)PHP从1994年起经历多次版本迭代,适应新技术趋势。2)目前广泛应用于电子商务、内容管理系统等领域。3)PHP8引入JIT编译器等功能,提升性能和现代化。4)使用OPcache和遵循PSR-12标准可优化性能和代码质量。

PHP的未来将通过适应新技术趋势和引入创新特性来实现:1)适应云计算、容器化和微服务架构,支持Docker和Kubernetes;2)引入JIT编译器和枚举类型,提升性能和数据处理效率;3)持续优化性能和推广最佳实践。

在PHP中,trait适用于需要方法复用但不适合使用继承的情况。1)trait允许在类中复用方法,避免多重继承复杂性。2)使用trait时需注意方法冲突,可通过insteadof和as关键字解决。3)应避免过度使用trait,保持其单一职责,以优化性能和提高代码可维护性。

依赖注入容器(DIC)是一种管理和提供对象依赖关系的工具,用于PHP项目中。DIC的主要好处包括:1.解耦,使组件独立,代码易维护和测试;2.灵活性,易替换或修改依赖关系;3.可测试性,方便注入mock对象进行单元测试。

SplFixedArray在PHP中是一种固定大小的数组,适用于需要高性能和低内存使用量的场景。1)它在创建时需指定大小,避免动态调整带来的开销。2)基于C语言数组,直接操作内存,访问速度快。3)适合大规模数据处理和内存敏感环境,但需谨慎使用,因其大小固定。

PHP通过$\_FILES变量处理文件上传,确保安全性的方法包括:1.检查上传错误,2.验证文件类型和大小,3.防止文件覆盖,4.移动文件到永久存储位置。

JavaScript中处理空值可以使用NullCoalescingOperator(??)和NullCoalescingAssignmentOperator(??=)。1.??返回第一个非null或非undefined的操作数。2.??=将变量赋值为右操作数的值,但前提是该变量为null或undefined。这些操作符简化了代码逻辑,提高了可读性和性能。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境

Atom编辑器mac版下载
最流行的的开源编辑器

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

SublimeText3 Linux新版
SublimeText3 Linux最新版

SublimeText3汉化版
中文版,非常好用