<?php
class 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,谁能解释一下
class 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,谁能解释一下
public 和 private结果是不一样的,当属性变为public,this就代表子类,能解释吗
class 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结果不同
public 共有的,可任意访问、继承、覆盖
没明白,怎么解释public 和 private结果不同因为对于php来说 public 和 private 是2种不同的修饰也就是说,当父类是private m时,子类的public m其实只是子类的内部方法,而和父类完全没有关系,当调用run时,首先回去run声明的空间寻找private的方法,如果找到,则直接执行,否则回去当前对象的空间寻找public或者protected的方法,如果还没有找到,并且有extends class 则会去class的空间找,仍然没有的话,则会报错。
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情况下不同,谢谢
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()
class 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 指向的是对象,而不是类
实例化后,无论是基类还是继承类的方法都在对象中
具体执行的是哪个方法由 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
就像 $obj=new child(); 后的 $obj 一样
如果你是在对象内部访问对象的方法和属性的话,总不能老是要把 $obj 传进去吧?
所以就有了 $this 这个载体其实所有面向对象的语言中都有这个 this,也的确迷糊了众多的初学者。其实没有什么好不理解的
this 就是对象自己
但是根据第二段代码,父类run里面的this调用了子类对象的方法,所以结论,this指向子类,和第一段代码矛盾this到底指向父类还是子类对象
那么,父类方法中的this,到底引用的是父类,还是子类对象?(难道存在父类对象),根据php代码的运行结果,明显矛盾,一会指向父类一会指向子类
你说的这个我明白,我真正不明白的地方是,子类继承父类方法function a()(这个方法a()内用到了this),这个继承过来的this,到底是谁的this?13楼的回答看得出来他明白了我是什么意思,但是解释的有矛盾,而版主还是没理解我的意思,我不是不明白private和this的规则,我市不知道在继承过程中,this传到了子类的过程中,指向发生了改变还是怎么回事,你的前2个代码的运行结果,明显是php运行机制中的矛盾点
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情况下不同,谢谢
最后回复一帖,不想在这个问题多做纠结了首先,看下面这个例子
<?php
class 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();但愿你能明白。