2017-02-24 83 views
2

一位用户发布了对PHP Visibility manual page的评论。这是第二大投票评论。他使用此代码示例:子类访问父类的私有方法?

<?php 
abstract class base { 
    public function inherited() { 
     $this->overridden(); 
    } 
    private function overridden() { 
     echo 'base'; 
    } 
} 

class child extends base { 
    private function overridden() { 
     echo 'child'; 
    } 
} 

$test = new child(); 
$test->inherited(); 
?> 

输出将是“基础”。

据我所知:“子”类继承了继承的()方法。不会继承覆盖的()方法,因为它是私有的,但是定义了它自己的方法。但是当测试对象(子类的实例)运行inherited()方法时,它会输出“base”。

所以我的问题是:

  1. 为什么孩子跑到它不能访问的方法?
  2. 为什么它不运行自己重新定义的方法?

回答

2

由于在子类中您没有定义任何function inherited(),因此必须调用其父方法。正如您引用的评论所说:

...私有方法只对定义它们的类可见,而子类不会看到父级的私有方法。 ...

这就是说,因为你不必引用孩子的私有方法,任何公开的方法,如:

class child extends base { 
    public function inherited() { 
     $this->overriden(); 
    } 

    // ... 

从我的角度来看,调用$test->inherited()将使用范围的父类,所以,如果您创建父类的实例并调用$this->inherited()会发生什么情况。它会输出基地

试着做我上面说的:在子类中,复制并粘贴父类的继承方法。它会输出孩子

我不确定这是否得到很好的解释,如果是的话,也许它可以帮助你更多地理解,如果不是,有人可以帮助我改善它。

+0

简单的总结:如果它会输出'child',那意味着父对'inherited'的实现会调用孩子的'overridden'实现,这显然违反了“只对定义它们的类可见”规则。 – deceze

+0

是的,如果你想'$ test-> inherited()'输出'child',你只需要在子类中创建'inherited()'函数。谢谢你的评论@deceze – Condorcho

+0

阿哈,这是关于我如何(也许我并不孤单)理解继承:事实上作为一种方法和属性COPYING。所以我猜想,当子类继承了'inherited'方法时,它实际上得到了它的一个副本。从这个角度看,孩子调用自己的“继承”方法,然后调用孩子的“重写”方法并输出“孩子”。 好吧,我意识到这不是它的实际工作原理。 :-) –