我对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();
?>
http://www.php.net/manual/en/language.oop5.visibility.php
此示例输出
Bar::testPrivate
Foo::testPublic
请你解释一下这是怎么发生的?
为什么两个testPublic()
都没有被调用?
我在Bar类构造中添加了 var_dump($this)
。它打印object(Foo)[1]
。我知道的是私有属性可以用同一个类调用。
然后如何调用“Bar::testPrivate
”?
答案 0 :(得分:6)
然后如何调用“Bar :: testPrivate”?
当您致电$myFoo->test()
时,它会在Bar
的上下文中运行代码,因为Foo
类没有覆盖它。
在Bar::test()
内,当$this->testPrivate()
被调用时,解释器将首先查看Foo
,但该方法是私有的(并且无法从{{调用来自后代类的私有方法) 1}}),所以它向上一级,直到找到合适的方法;在这种情况下,这将是Bar
。
相反,当调用Bar::testPrivate()
时,解释器会立即在$this->testPublic()
中找到合适的方法并运行它。
修改强>
为什么不调用testPublic()?
运行Foo
时只调用一个方法,最远的一个(就基于距基类的距离而言)。
如果$this->testPublic()
还需要执行父实现,则应在该方法中编写Foo::testPublic()
。
答案 1 :(得分:2)
你的函数位于Bar
类,你使用魔法$this
指针来调用成员函数。
尝试将函数test()
移动到Foo
类,看看会发生什么。输出应为:
Foo::testPrivate
Foo::testPublic
在您的示例中,调用了Bar的私有函数,因为它仅适用于该类。类Foo中没有test
函数,因此Bar
类的测试函数无法调用它们。
然后,由于函数重载,调用了类Foo
的公共函数而不是Bar
。
这两个类都具有该名称的功能,因此子类的功能具有重要性。
答案 2 :(得分:1)
Private
并不代表你不能称之为。这意味着您只能从当前类中调用它。 Public
表示您可以从任何类调用它。
要致电Bar::testPrivate
,请尝试以下方法:
$Bar->testPublic();
或
parent::testPublic();
但是,您无法拨打$Bar->testPrivate()
,因为该方法为private
。
答案 3 :(得分:1)
你打电话
$myFoo->test();
参见函数test
:
public function test() {
$this->testPrivate();
$this->testPublic();
}
当在Bar
类的实例(包括继承的类)上调用它时,它会调用testPrivate
和testPublic
。
这些方法在类Foo
中被覆盖,这意味着使用了Foo
的方法。您始终可以调用基类的方法:
// in Foo
public function testPublic() {
parent::testPublic();
echo "Foo::testPublic\n";
}
Bar::testPrivate
被调用,因为它是private
而不会被Foo::testPrivate
覆盖。
答案 4 :(得分:1)
我猜用户'omega在2093点es'(http://www.php.net/manual/en/language.oop5.visibility.php#109324)的评论是描述同样的事情。 有句说:“在父类中定义的方法不能访问从它们继承的类中定义的私有方法。但是它们可以访问受保护的。”
在你的情况下,$this
方法中的Bar::test()
对象属于Foo
类型(你的var_dump证明了这一点)。因为Foo::testPrivate()
方法是私有的,所以无法从父类Bar访问它,并且唯一可以访问的方法仍然是Bar::testPrivate()
(尝试注释定义,你会得到致命的错误)。这就是为什么第一个输出是Bar::testPrivate
。
行$this->testPublic();
调用Foo::testPublic()
方法,因为$this
属于Foo
类型,方法定义为公开。
简而言之,私有方法只能从定义它们的类中访问。它们既不能从子类也不能从父类访问。
要使子类或父类可访问该方法,请使其受到保护。例如,如果您在两个类中都保护testPrivate()
方法,则会打印Foo::testPrivate Foo::testPublic
。
答案 5 :(得分:0)
Foo类扩展了类Bar。然后在Bar中定义函数测试。在这个函数中有两个调用。一个是公共的,一个是私人职能吧。