I saw this in the PHP OOP manual http://www.php.net/manual/en/language.oop5.visibility.php and I can't get my head around why the output is not: Foo::testPrivate Foo::testPublic
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(); // Bar::testPrivate
// Foo::testPublic
In some cases, it is easy to notice that you want a private method on the Bar class, but you also wants the Foo class to access it.
But wait, it is public or private?
Here comes the protected modifier.
When a method is private, only the class itself can call the method.
When a method is public, everyone can call it, like a free party.
When a method is protected, the class itself can call it and also whoever inhered this method (children) will be able to call it as a method of their own.
I posted the same question few days ago... because this behaviour wasnt logical for me either. $this is always referred to the current object which it is used in. In my opinion example like this should throw an error or warning or something. Because in the above example you are actually accessing private members :SSS WHICH SUPPOSED TO BE INACCESSIBLE!
It's all about the visibility of the variables / methods.
You'll notice that in the
Bar
class, the methodtestPrivate()
isprivate
. That means that ONLY itself can access that method. No children.So when
Foo
extendsBar
, and then asks to run thetest()
method, it does two things:testPublic()
method because it's public, andFoo
has the right to override it with it's own version.test()
onBar
(sincetest()
only exists onBar()
).testPrivate()
is not overridden, and is part of the class that holdstest()
. Therefore,Bar::testPrivate
is printed.testPublic()
is overridden, and is part of the inheriting class. Therefore,Foo::testPublic
is printed.