Reputation: 4650
I have difficulties in understanding why we get the output of this code:
<?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();
?>
So Foo extends Bar. $myfoo is an obect of the class Foo. Foo doesn't have a method, called test(), so it extends it from its parent Bar. But why the result of test() is
Bar::testPrivate
Foo::testPublic
Can you please explain me why the first isn't Foo::testPrivate, when this parent's method is overridden in the child?
Thank you very much in advance!
Upvotes: 20
Views: 1265
Reputation: 15614
This is not PHP specific. Inheritance rules call for protected and public functions to be overridable. Private functions have their own scope and are invisible for the generalized class.
Please find below the same situation in Java, same result:
Bar::testPrivate
Foo::testPublic
Except you might get a warning
The method testPrivate() from the type Foo is never used locally Foo.java
since Java is compiled.
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();
}
}
Upvotes: 3
Reputation: 17831
Because private
means private
. No other class, not even child-classes know about Bar::testPrivate()
and therefore cannot override something they don't even know about.
You can use Foo::testPrivate()
only inside Foo
. Because that's what private
is all about.
More information: Strange behavior when overriding private methods
Upvotes: 5
Reputation: 3714
Probably becuase testPrivate
is, as the name already suggests, a private method and won't be inherited / overwritten by class inheritance.
On the php.net manual page you probably got that code from it explicitely states that We can redeclare the public and protected method, but not private
So, what exactly happens is the following: The child class will not redeclare the method testPrivate
but instead creates it's own version in the "scope" if the child object only. As test()
is defined in the parent class, it will access the parents testPrivate
.
If you would redeclare the test
function in the child class, it should access the childs? testPrivate()
method.
Upvotes: 12
Reputation: 45731
Private methods are not visible to anything but the declaring class. Since you call testPrivate
from the parent class, the only method it has access to is its own declaration of the method. Thus you get the output you see. Had the access modifier been protected
, however, then you would get the output you expect, since protected methods are visible throughout the inheritance chain.
Upvotes: 6
Reputation: 90863
private
members cannot be overridden, only public and protected ones can. It means that, in fact, testPrivate
is not overridden, so Bar
cannot see it and still calls its own testPrivate
.
Upvotes: 5