PHP继承的问题,调用父类的方法this指向问题。

classa{publicfunctionm(){echo'aa';}publicfunctionrun(){$this->m();}}classbextendsa{pu... class a{
public function m(){
echo 'aa';
}
public function run(){
$this->m();
}
}

class b extends a{
public function m(){
echo 'bb';
}
}

$li = new b();
$li->run();
谁能跟我分析一下这为什么是访问的b类里面的m方法,如果把a类的m方法权限改为private,又为什么变成访问的是a类的m方法了。。
声明一个类的时候,如果这个类继承某个类,那么这父类的方法在子类中是如何体现的,完全复制一份吗?
展开
 我来答
cmoooo
推荐于2017-09-23 · TA获得超过3587个赞
知道小有建树答主
回答量:741
采纳率:0%
帮助的人:669万
展开全部

我来说一说:


【一】…………public(仅有)属性和方法的继承…………

class a{
public $var = 'var a <br/>';
public function m(){
echo 'fun a <br/>';
}
public function run(){
echo $this->var;
$this->m();
}
}

class b extends a{
public $var = 'var b <br/>';
public function m(){
echo 'fun b <br/>';
}
}
$li = new b();
$li->run();
echo '<hr>';
var_dump($li);

输出:

var b 
fun b 
————————————————————————————
object(b)[1]
  public 'var' => string 'var b <br/>' (length=11)

在这段代码中所表示的,是我们常见的一种继承方式,同为公有属性的$var 和公有方法m()


在这里,$var和m()都被继承并覆写,实例化过后,内存中只有一个$var实例,通过var_dump($li);我们可以看到它。



【二】…………private(私有)属性和方法的继承…………

class a{
private $var = 'var a <br/>';
private function m(){
echo 'fun a <br/>';
}
public function run(){
echo $this->var;
$this->m();
var_dump($this);
echo '<br/><br/>';
}
}

class b extends a{
private $var = 'var b <br/>';
private function m(){
echo 'fun b <br/>';
}
public function run(){
echo $this->var;
$this->m();
var_dump($this);
echo '<br/><br/>';
parent::run();
}
}
$li = new b();
$li->run();
echo '<hr>';
var_dump($li);

输出:

var b 
fun b 
object(b)[1]
  private 'var' => string 'var b <br/>' (length=11)
  private 'var' (a) => string 'var a <br/>' (length=11)
.
.
var a 
fun a 
object(b)[1]
  private 'var' => string 'var b <br/>' (length=11)
  private 'var' (a) => string 'var a <br/>' (length=11)
.
————————————————————————————————
object(b)[1]
  private 'var' => string 'var b <br/>' (length=11)
  private 'var' (a) => string 'var a <br/>' (length=11)

这个时候,我们可以看到,在调用run方法时,首先它会调用到b类的私有属性$var 和私有方法m(),随后,又使用parent::run()调用父类的run()方法,我们可以看到,父类的run()方法调用后,它所调用的属性和方法,都是a类的两个私有属性和方法,这种形式,和你的问题一致;


而它与$this指向无关,我们可以在这里看到,两个$this都是指向b类。


而最有意思的是,在$li句柄中,我们却看到了两个属性!一个是b类的属性,一个是a类的属性,这两个属性同时存在着,那么,私有方法也自然是同时存在着。


【三】…………私有属性和方法能不能被继承…………

class a{
private $var = 'var a <br/>';
private function m(){
echo 'fun a <br/>';
}
}
class b extends a{
public function run(){
echo $this->var;
$this->m();
}
}
$li = new b();
$li->run();

输出:

Notice: Undefined property: b::$var in E: ... on Line 9
Fatal error: Call to private method a::m() from context 'b' in E: ... on Line 10

这可以证明,私有属性和方法,无法被继承,所以,你的代码示例中所说,将a类的m()方法更改为private后,会显示aa的属性,也就可以理解明白了。

更多追问追答
追问
将a类的m()方法更改为private后,会显示aa的属性   还是无法理解,虽然没有继承过去,但其子类b也是调动个m方法,而它与$this指向无关,我们可以在这里看到,两个$this都是指向b类。你这里说这this指向的是b。那应该还是调用b类的m方法才对的啊
追答
“将a类的m()方法更改为private后,会显示aa的属性”这句话是我打字太顺了手,出了差错,没有最后“的属性”三字,是:“将a类的m()方法更改为private后,会显示aa”

它确实是与$this的指向无关的,但却与$this的位置有关系。

私有的属性和方法,只能够在该类中被调用,像你的这个程序中,没有属性,只有方法,而run()方法虽然被继承到了b类中,但它仍然属于a类的方法,并不是b类的,所以,它里面的$this->m()自然就是a类中私有的方法m(),而非b类中“新定义”的公有方法m(),这就是说,内存中实际上是有两个m()方法的,一个属于a类,一个属于b类,两个毫不相关,各是各的。

当你调用继承自a类的方法run()时,run()方法中的$this,这个$this位于a类之中,隶属于a类,所以a类中的私有方法m()是对其开放的,然后我们再看,如果这个$this出现在b类中,那这个时候,这个b类中的$this->m(),指向的就不再是a类的私有方法m()了,而是b类中“新定义的”的m()。

为什么说是“新定义”?因为a类中的m()方法是私有的,无法继承嘛,所以b类的m()方法是“新定义”的。

这里面有一个弯,你反过来再想想,对于a类来说,a类里的run()函数是不是属于a类的?是吧?

那么,在run()方法中使用$this,还无法访问它里面的私有属性,却是跑到其它地方去访问一个“新定义”的一个新方法,这才叫奇怪不是?

所以,这个现象是正常的,而我们却是以“为什么我把public改为private,它就变了呢?”这个先入为主的思想给误导了。

不知道你有没有理解?
只牵佑手
2013-06-11 · TA获得超过151个赞
知道小有建树答主
回答量:117
采纳率:0%
帮助的人:80.8万
展开全部
首先,你new的是b类,那你就可以表用b类里的所有方法,而b类继承了a类,那就是相当于b类拥有a类的全部方法,所以你当然是可以访问run函数的,而run函数是调用的$this本类的m方法,你之前实例化的是b类,b类重写了m方法,那当然是输出b类的m方法的结果。当改为private时,成为私有的,私有的是不可以被继承的,所以b类的m方法也不能算是重写a类的m方法,应该算是两个方法只是名字相同罢了,那第二次$this->m()自然是输出a类的m方法结果了(第二次m没有被重写,只能输出a类的结果)。纯属个人的看法
更多追问追答
追问
第二次输出的是a类的方法那,是不是说明 这$this->m();这里的this指向的是a类,不是指向b这个子类,那为什么第一次的this指向的是b这个子类呢??方法被重写了,那不代表父类的这个方法不存在了吧?要访问父类的方法还是可以访问的。
追答
public时,实例化b类,方法m被重写,那么内存中应该是只有一个方法m,而不会有两个m方法,所以只会输出b类里m方法的结果。这个可以明白吧。
而第二次private时,内存中就两个m函数,那自然就是访问自己的私有属性m函数了,即a类的m方法
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
轻松又清澈的纯真A
2013-06-11 · TA获得超过320个赞
知道小有建树答主
回答量:323
采纳率:100%
帮助的人:363万
展开全部
子类就会继承父类所有公有的和受保护的方法,所以当修改为私有时输出的是aa。
参考:http://cn2.php.net/manual/zh/language.oop5.inheritance.php
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
du瓶邪
推荐于2017-09-13 · TA获得超过2.4万个赞
知道大有可为答主
回答量:1.7万
采纳率:100%
帮助的人:2911万
展开全部
parent和$this的作用域不同,效率没差别,一般对象方法用$this即可,parent一般是为了在覆盖父类方法后还需要调用该方法已实现的功能而使用的,比如父类有个get方法,子类也有个get方法,但是子类想在父类的get方法基础上继续做些操作,就只能用parent::get()。
class A

{

public function get()

{

return "something";

}

}

class B extends A

{

public function get()

{

// 不能用$this->get()调用自己,否则死循环递归了

return parent::get() . " and others";

}

}
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式