php manual visibility example mixed up

I got confused from an example in a PHP manual. This is about visibility. Here is an example.

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

This example prints

 Bar::testPrivate Foo::testPublic 

Please can you explain how this happened?

why are both testPublic() not called?

I put var_dump($this) in the construction of the Bar class. It prints object(Foo)[1] . I know that private properties can be called in the same class.

Then what is the name of " Bar::testPrivate "?

+6
source share
6 answers

Then how is "Bar :: testPrivate" called?

When you call $myFoo->test() , it runs the code in the context of Bar , because the Foo class does not override it.

Inside Bar::test() , when the called $this->testPrivate() is called, the interpreter will look at Foo , but this method is private (and private methods from child classes cannot be called from Bar ), so it goes to one level until it finds a suitable method; in this case it will be Bar::testPrivate() .

In contrast, when the call to $this->testPublic() is called, the interpreter immediately finds the appropriate method in Foo and starts it.

Edit

why are both testPublic () not called?

Only one method is called when you run $this->testPublic() , the farthest (in terms of distance to the base class).

If Foo::testPublic() also needs to execute a parent implementation, you must write parent::testPublic() inside this method.

+6
source

Your function lies in the Bar class, and you use the $this magic pointer to call member functions.

Try moving the test() function to the Foo class and see what happens. The output should be:

 Foo::testPrivate Foo::testPublic 

In your example, the private function Bar was called because it applies only to this class. The Foo class does not have the test function in it, and therefore the test function from the Bar class does not have access to call them.

Then, instead of Bar , the public function of the Foo class was called due to function overloading.

Both classes have a function of this name, therefore the function of the child class is important.

+2
source

Private does not mean you cannot name it. This means that you can only call it from the current class . Public means that you can call it from any class .

To call Bar::testPrivate , try the following:

 $Bar->testPublic(); 

or

 parent::testPublic(); 

BUT, you cannot call $Bar->testPrivate() , because the method is Private .

+1
source

You call

 $myFoo->test(); 

See the test function:

 public function test() { $this->testPrivate(); $this->testPublic(); } 

When this is called on an instance of the Bar class (including inherited classes), it calls testPrivate and testPublic .

These methods are overridden in the Foo class, that is, the Foo methods are used. You can always call the base class method:

 // in Foo public function testPublic() { parent::testPublic(); echo "Foo::testPublic\n"; } 

Bar::testPrivate is called because it is private and is not overridden by Foo::testPrivate .

More details here or here .

+1
source

I think the comment by omega at 2093 dot es ( http://www.php.net/manual/en/language.oop5.visibility.php#109324 ) describes the same thing. It says: "Methods defined in the parent class cannot access private methods defined in the class that inherits them. However, they can access protected methods."

In your case, the $this object in the Bar::test() method is of type Foo (your var_dump proves this). Since the Foo::testPrivate() method is private, access to it from the parent class is not possible, and the only method available to it is Bar::testPrivate() (try commenting on the definition and you will get a fatal error). Therefore, the first output is Bar::testPrivate .

String $this->testPublic(); calls the Foo::testPublic() method, because $this is of type Foo , and the method is defined as public.

In short, private methods are only available from the class where they are defined. They can not be addressed neither from the child, nor from the parent classes.

To make an accessible method from a child or parent class, it will be protected. For example, if you create a testPrivate() method protected in both classes, it will print Foo::testPrivate Foo::testPublic .

+1
source

The Foo class extends the Bar class. Then the test function called wich is defined in Bar. There are two calls to this function. One for the public and one for a private function in the Bar class.

0
source

Source: https://habr.com/ru/post/909289/


All Articles