我很难理解为什么我们得到这段代码的输出:
<?php
class Bar
{
public function test() {
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "Bar::testPublic\n";
}
private function testPrivate() {
echo "Bar::testPrivate\n";
}
}
class Foo extends Bar
{
public function testPublic() {
echo "Foo::testPublic\n";
}
private function testPrivate() {
echo "Foo::testPrivate\n";
}
}
$myFoo = new foo();
$myFoo->test();
?>
所以Foo扩展了Bar。 $ myfoo是Foo类的一个对象。 Foo没有一个叫做test()的方法,所以它从它的父Bar扩展它。但是为什么test()的结果是
Bar::testPrivate
Foo::testPublic
你可以解释一下,为什么第一个不是Foo :: testPrivate,当这个父方法在孩子中被覆盖时?
非常感谢你!
答案 0 :(得分:12)
正如名称已经暗示的那样,testPrivate
可能是私有方法,并且不会被类继承继承/覆盖。
在php.net手册页上,您可能会从中明确说明We can redeclare the public and protected method, but not private
因此,具体如下:子类不会重新声明方法testPrivate
,而是仅在子对象中在“范围”中创建自己的版本。由于test()
在父类中定义,它将访问父项testPrivate
。
如果要重新声明子类中的test
函数,它应该访问子项? testPrivate()
方法。
答案 1 :(得分:5)
private
成员不能被覆盖,只有公共成员和受保护成员才能被覆盖。这意味着,事实上,testPrivate
不被覆盖,因此Bar
无法看到它,仍然会调用自己的testPrivate
。
答案 2 :(得分:5)
除了声明类之外,其他任何内容都不会显示私有方法。由于您从父类调用testPrivate
,因此它可以访问的唯一方法是它自己的方法声明。这样你就得到了你看到的输出。但是,如果访问修饰符为protected
,那么您将获得所期望的输出,因为受保护的方法在整个继承链中都是可见的。
答案 3 :(得分:5)
因为private
表示private
。没有其他课程,甚至儿童课程都不了解Bar::testPrivate()
,因此无法覆盖他们甚至不知道的事情。
您只能在Foo::testPrivate()
内使用Foo
。因为这就是private
的全部内容。
答案 4 :(得分:3)
答案 5 :(得分:3)
这不是特定于PHP的。继承规则要求保护和公共函数可以覆盖。私有函数有自己的范围,对于通用类是不可见的。
请在下面找到相同的Java情况,结果相同:
Bar::testPrivate
Foo::testPublic
除非您收到警告
The method testPrivate() from the type Foo is never used locally Foo.java
因为编译了Java。
public class Bar
{
public void test() {
this.testPrivate();
this.testPublic();
}
public void testPublic() {
System.out.println("Bar::testPublic\n)");
}
private void testPrivate() {
System.out.println( "Bar::testPrivate\n");
}
}
public class Foo extends Bar {
public void testPublic() {
System.out.println("Foo::testPublic\n");
}
private void testPrivate() {
System.out.println("Foo::testPrivate\n");
}
public static void main(String[] args) {
Foo myFoo = new Foo();
myFoo.test();
}
}