PHP method scope binding
Clash Royale CLAN TAG#URR8PPP
up vote
6
down vote
favorite
I am confused by how PHP call method in parent-children hierarchy. Here is the code
class A
private function foo()
echo "A!";
public function test()
$this->foo();
class C extends A
public function foo()
echo 'C!';
$c = new C();
$c->test();
The output is A!
consider another example, but only change the foo() method visibility in class A to be public.
class A
public function foo()
echo "A!";
public function test()
$this->foo();
class C extends A
public function foo()
echo 'C!';
$c = new C();
$c->test();
This output is C!
Any explanation is welcome.
php oop object
add a comment |Â
up vote
6
down vote
favorite
I am confused by how PHP call method in parent-children hierarchy. Here is the code
class A
private function foo()
echo "A!";
public function test()
$this->foo();
class C extends A
public function foo()
echo 'C!';
$c = new C();
$c->test();
The output is A!
consider another example, but only change the foo() method visibility in class A to be public.
class A
public function foo()
echo "A!";
public function test()
$this->foo();
class C extends A
public function foo()
echo 'C!';
$c = new C();
$c->test();
This output is C!
Any explanation is welcome.
php oop object
Private methods are only visible to the actual class, protected is visible only inside the class (any child class). Public is for the world to see. In your fist example callingfoo
will fail in any case except from within the class it's defined within. When you override foo in the child, it doesn't replace the private foo method because it's not visible to the C class at all.
â ArtisticPhoenix
2 hours ago
3
@ArtisticPhoenix thanks for comment, but I don't think that solve my confusion. Maybe you can explain in more details using above example.
â Nero
2 hours ago
@Artisticfoo
is only called from within the class that defines it. The question is whytest
sticks to callingA::foo
instead ofC::foo
.
â decezeâ¦
2 hours ago
I tried, it's like relativity it's all depends on the reference frame of the observer. You can't think of it in terms of the Global space (space outside the classes).
â ArtisticPhoenix
38 mins ago
add a comment |Â
up vote
6
down vote
favorite
up vote
6
down vote
favorite
I am confused by how PHP call method in parent-children hierarchy. Here is the code
class A
private function foo()
echo "A!";
public function test()
$this->foo();
class C extends A
public function foo()
echo 'C!';
$c = new C();
$c->test();
The output is A!
consider another example, but only change the foo() method visibility in class A to be public.
class A
public function foo()
echo "A!";
public function test()
$this->foo();
class C extends A
public function foo()
echo 'C!';
$c = new C();
$c->test();
This output is C!
Any explanation is welcome.
php oop object
I am confused by how PHP call method in parent-children hierarchy. Here is the code
class A
private function foo()
echo "A!";
public function test()
$this->foo();
class C extends A
public function foo()
echo 'C!';
$c = new C();
$c->test();
The output is A!
consider another example, but only change the foo() method visibility in class A to be public.
class A
public function foo()
echo "A!";
public function test()
$this->foo();
class C extends A
public function foo()
echo 'C!';
$c = new C();
$c->test();
This output is C!
Any explanation is welcome.
php oop object
php oop object
edited 2 hours ago
asked 2 hours ago
Nero
587312
587312
Private methods are only visible to the actual class, protected is visible only inside the class (any child class). Public is for the world to see. In your fist example callingfoo
will fail in any case except from within the class it's defined within. When you override foo in the child, it doesn't replace the private foo method because it's not visible to the C class at all.
â ArtisticPhoenix
2 hours ago
3
@ArtisticPhoenix thanks for comment, but I don't think that solve my confusion. Maybe you can explain in more details using above example.
â Nero
2 hours ago
@Artisticfoo
is only called from within the class that defines it. The question is whytest
sticks to callingA::foo
instead ofC::foo
.
â decezeâ¦
2 hours ago
I tried, it's like relativity it's all depends on the reference frame of the observer. You can't think of it in terms of the Global space (space outside the classes).
â ArtisticPhoenix
38 mins ago
add a comment |Â
Private methods are only visible to the actual class, protected is visible only inside the class (any child class). Public is for the world to see. In your fist example callingfoo
will fail in any case except from within the class it's defined within. When you override foo in the child, it doesn't replace the private foo method because it's not visible to the C class at all.
â ArtisticPhoenix
2 hours ago
3
@ArtisticPhoenix thanks for comment, but I don't think that solve my confusion. Maybe you can explain in more details using above example.
â Nero
2 hours ago
@Artisticfoo
is only called from within the class that defines it. The question is whytest
sticks to callingA::foo
instead ofC::foo
.
â decezeâ¦
2 hours ago
I tried, it's like relativity it's all depends on the reference frame of the observer. You can't think of it in terms of the Global space (space outside the classes).
â ArtisticPhoenix
38 mins ago
Private methods are only visible to the actual class, protected is visible only inside the class (any child class). Public is for the world to see. In your fist example calling
foo
will fail in any case except from within the class it's defined within. When you override foo in the child, it doesn't replace the private foo method because it's not visible to the C class at all.â ArtisticPhoenix
2 hours ago
Private methods are only visible to the actual class, protected is visible only inside the class (any child class). Public is for the world to see. In your fist example calling
foo
will fail in any case except from within the class it's defined within. When you override foo in the child, it doesn't replace the private foo method because it's not visible to the C class at all.â ArtisticPhoenix
2 hours ago
3
3
@ArtisticPhoenix thanks for comment, but I don't think that solve my confusion. Maybe you can explain in more details using above example.
â Nero
2 hours ago
@ArtisticPhoenix thanks for comment, but I don't think that solve my confusion. Maybe you can explain in more details using above example.
â Nero
2 hours ago
@Artistic
foo
is only called from within the class that defines it. The question is why test
sticks to calling A::foo
instead of C::foo
.â decezeâ¦
2 hours ago
@Artistic
foo
is only called from within the class that defines it. The question is why test
sticks to calling A::foo
instead of C::foo
.â decezeâ¦
2 hours ago
I tried, it's like relativity it's all depends on the reference frame of the observer. You can't think of it in terms of the Global space (space outside the classes).
â ArtisticPhoenix
38 mins ago
I tried, it's like relativity it's all depends on the reference frame of the observer. You can't think of it in terms of the Global space (space outside the classes).
â ArtisticPhoenix
38 mins ago
add a comment |Â
6 Answers
6
active
oldest
votes
up vote
4
down vote
accepted
Rule: private
and final
methods on an object will always be called directly, without consulting the override table.
This rule is baked into the engine:
/* Check if this calls a known method on $this */
if (opline->op1_type == IS_UNUSED && opline->op2_type == IS_CONST &&
CG(active_class_entry) && zend_is_scope_known())
zend_string *lcname = Z_STR_P(CT_CONSTANT(opline->op2) + 1);
fbc = zend_hash_find_ptr(&CG(active_class_entry)->function_table, lcname);
/* We only know the exact method that is being called if it is either private or final.
* Otherwise an overriding method in a child class may be called. */
if (fbc && !(fbc->common.fn_flags & (ZEND_ACC_PRIVATE
"Why", you ask? The answer is: because that's how it works. In language design, this is called "name hiding", and it's up to the language to specify how name hiding works. Take C++ for example. It has well-defined, and complex name hiding rules. PHP has its own rules. They're different from C++. But they're unique to PHP. This is just something you have to memorize about the language.
I admit the docs could better spell this out, however.
add a comment |Â
up vote
2
down vote
This is the behavior in most languages (by design).
If a method is private
, $this->method()
will call it directly (ignore the derived class's method)
If a method is virtual
(this concept comes from C++, in PHP and Java, all public/protected methods are virtual
), $this->method()
will call the derived class's method.
Rule is rule, it is an OOP concern. For example, in OOP we may want to make sure a method never got overridden, then we can make it private
. If a developer overrides it by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation. Thanks to @deceze
Is there an "official" reasoning for this? What I'd cobble together as an explanation would be something like: child classes should not be aware of the existence ofprivate
methods, if they override them it would be by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation�
â decezeâ¦
2 hours ago
Thanks. you just remind me something and it's explained in the office doc. It has the same explanation as yours. the private method has higher precedence.
â Nero
2 hours ago
@deceze yes, it is the OOP concern. I agree with your explanation
â shawn
2 hours ago
My English is not very good, maybe you can help to edit the answer :) @deceze
â shawn
2 hours ago
1
@deceze Yes, there is an official reason...
â bishop
17 mins ago
 |Â
show 1 more comment
up vote
1
down vote
I think the answer lies on the official documentation. doc here
In non-static contexts, the called class will be the class of the object instance. Since $this-> will try to call private methods from the same scope
As a note, though this could eliminate my confusion, simply saying "that is the way it is" seem not enough. Because it's weird behavior. It's not as clear as the late static binding nor respect to the called scope class C (which can be verified using get_called_class() in test() method ).
Yes, this is the documented reason, but I feel it could be clarified. As unsatisfying as it may sound, that's just the way it is. :)
â bishop
18 mins ago
add a comment |Â
up vote
1
down vote
Ok let me try [Again]
Basically both methods exist side by side.
Private by design means that this thing (method or property) is not visible or accessible or writable by anything besides the class it was defined in. So children cannot use it in any way nor modify it in any way. This is the behaviour of private.
The why (the reason) behind the concept, is to guarantee a specific functionality (or value, of properties) no matter how the class is extended. This is good because when designing the Parent class we may not know how it will be used by any extending classes, and there may be functionality that is critical and should not be changed. This gives us a way to guarantee that in our code without knowing the implementation of the children.
One reason they can exist side by side, is inside of the child class when you call $this->foo()
there is no ambiguity about which foo is being called as only the public version C::foo()
visible to class C
(the child) class.
class A
private function foo()
echo "A!";
public function parentTest()
//if we used C::foo() from here Overriding A::foo().
//having a concept of private would lose all meaning
//because we would be allowing the child to modify it
$this->foo();
class C extends A
public function foo()
echo 'C!';
public function childTest()
//A::foo() cannot be used from here
//so PHP knows to use C::foo()
$this->foo();
In short there is only one Foo available to the child class C::foo()
, so there is no way it can be confused with the private version A::foo()
by PHP. In this way both methods can exist without the child overriding the parents method.
Don't let me confuse you more here, because in some ways the childs method does override the parents. We can see this if we call $obj->foo()
from the global space. If we don't define foo in the child C
then we get an error. But if we do define a public one in C
it is used. Another thing that shows that it does overwrite (in some ways) is if we set the parent's copy A::foo()
to be final. In this case if we try to define C::foo()
we get an error as we would expect.
But (here is the important part), neither of these affect the functionality of the private stuff as far as the parent is concerned and so they do not violate the private principle.
Now for the parents call to its own private method.
This is where most people get confused and you asked:
When calling what is for all intents and purposes C::test, why does it prefer the private A::foo over the public C::foo
It doesn't because you are calling the private method from another method in the same class where the private one was defined.
If it preferred the child's method, then then there would be no point in having a private visibility because we would have just violated it by allowing the child to modify the method. In other words we would be using the child's functionality instead of that marked by private.
I will try to say the same things in a different way, maybe that will help (or it will just confuse you more...lol).
The reason you can have another method with the same name and it's own functionality (something I really don't care for and avoid) is because the parents private functionality does not enter the scope of the child class, so there is no way for PHP to get confused about what version private or public to use. It knows to use the public if not in the class it was defined in but to use the private if it is in the class it was defined in.
I hope that helps, that's the best I can do.
When calling what is for all intents and purposesC::test
, why does it prefer theprivate
A::foo
over thepublic
C::foo
?
â decezeâ¦
2 hours ago
It doesn't prefer it. Your thinking in terms of it over writing or replacing that method, which it doesn't do. It simply doesn't exist.
â ArtisticPhoenix
1 hour ago
1
Explanation like class A does not know about existence of class B seem make no sense to me especially when we're talking with my example. the way you try to prove this is wrong, because you use (new A)->test(); but in my case, it's (new C)->test(); They are different. You call parent directly and of course it won't know. In my case, it makes call from a child. Correct me if wrong.
â Nero
1 hour ago
1
Additionally, if you remove function foo() from class A, the one defined in child will be called. Dose this prove "class A is aware of class C's existence" ?
â Nero
1 hour ago
Dose this prove "class A is aware of class C's existence"
No because your calling it from an instance of the child. And even though you call the private method from an child instance private overrides that normal behaviour. If it didn't there would be no point in having it.
â ArtisticPhoenix
55 mins ago
 |Â
show 1 more comment
up vote
0
down vote
Because in first case you are not overriding the foo() in derived class C, because foo() is private.
But, in case two, foo() is public and is overridden by function foo() in class C
So, by basics of inheritance you can't override a private method and hence your foo() in class C has no existence in first case (keeping or deleting it does not matter) and the actual method of extended class A will be called since you have no right to override it in your class.
Try this:
public function test()
echo get_class($this);
$this->foo();
In both case it will echo C , not A. So, $this is object of C which cannot override private methods of A, hence foo() of C has no use when foo() exists in class A and is private.
New contributor
Your last paragraph underscores the reason for the confusion, I think, and your earlier paragraphs don't help clarify that confusion, in my opinion. If in both cases the object$this
is ofclass C
, then there's a reasonable expectation thatC::foo()
will be called regardless of the existence ofA::foo()
. However, the OP demonstrates that's not the case and wants to know why. The answer, as it turns out, cannot be explained by rationalization based on inheritance -- it's simply a rule the engine implements, and it must be memorized.
â bishop
23 mins ago
add a comment |Â
up vote
0
down vote
Private foo() is a part of class A, and A does not know about the existence of the C class. It can work without it.
When extending A class, C inherits all public and protected method of A, that's why test() is available. You would call the private foo() method of A class from within the test() method, not the one from C. Extending works in one direction only, you would not be able to call methods from C from within A. A can be instantiated without C and nothing can guarantee another class will extend it.
A does not know about the existence of the C class, but why after change visibility of foo method in class A make it know about the existence of the C class?
â Nero
1 hour ago
"Extending works in one direction only". Does it? The second scenario in the OP is an example whereA::test()
callsC::foo()
.
â bishop
15 mins ago
add a comment |Â
6 Answers
6
active
oldest
votes
6 Answers
6
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
4
down vote
accepted
Rule: private
and final
methods on an object will always be called directly, without consulting the override table.
This rule is baked into the engine:
/* Check if this calls a known method on $this */
if (opline->op1_type == IS_UNUSED && opline->op2_type == IS_CONST &&
CG(active_class_entry) && zend_is_scope_known())
zend_string *lcname = Z_STR_P(CT_CONSTANT(opline->op2) + 1);
fbc = zend_hash_find_ptr(&CG(active_class_entry)->function_table, lcname);
/* We only know the exact method that is being called if it is either private or final.
* Otherwise an overriding method in a child class may be called. */
if (fbc && !(fbc->common.fn_flags & (ZEND_ACC_PRIVATE
"Why", you ask? The answer is: because that's how it works. In language design, this is called "name hiding", and it's up to the language to specify how name hiding works. Take C++ for example. It has well-defined, and complex name hiding rules. PHP has its own rules. They're different from C++. But they're unique to PHP. This is just something you have to memorize about the language.
I admit the docs could better spell this out, however.
add a comment |Â
up vote
4
down vote
accepted
Rule: private
and final
methods on an object will always be called directly, without consulting the override table.
This rule is baked into the engine:
/* Check if this calls a known method on $this */
if (opline->op1_type == IS_UNUSED && opline->op2_type == IS_CONST &&
CG(active_class_entry) && zend_is_scope_known())
zend_string *lcname = Z_STR_P(CT_CONSTANT(opline->op2) + 1);
fbc = zend_hash_find_ptr(&CG(active_class_entry)->function_table, lcname);
/* We only know the exact method that is being called if it is either private or final.
* Otherwise an overriding method in a child class may be called. */
if (fbc && !(fbc->common.fn_flags & (ZEND_ACC_PRIVATE
"Why", you ask? The answer is: because that's how it works. In language design, this is called "name hiding", and it's up to the language to specify how name hiding works. Take C++ for example. It has well-defined, and complex name hiding rules. PHP has its own rules. They're different from C++. But they're unique to PHP. This is just something you have to memorize about the language.
I admit the docs could better spell this out, however.
add a comment |Â
up vote
4
down vote
accepted
up vote
4
down vote
accepted
Rule: private
and final
methods on an object will always be called directly, without consulting the override table.
This rule is baked into the engine:
/* Check if this calls a known method on $this */
if (opline->op1_type == IS_UNUSED && opline->op2_type == IS_CONST &&
CG(active_class_entry) && zend_is_scope_known())
zend_string *lcname = Z_STR_P(CT_CONSTANT(opline->op2) + 1);
fbc = zend_hash_find_ptr(&CG(active_class_entry)->function_table, lcname);
/* We only know the exact method that is being called if it is either private or final.
* Otherwise an overriding method in a child class may be called. */
if (fbc && !(fbc->common.fn_flags & (ZEND_ACC_PRIVATE
"Why", you ask? The answer is: because that's how it works. In language design, this is called "name hiding", and it's up to the language to specify how name hiding works. Take C++ for example. It has well-defined, and complex name hiding rules. PHP has its own rules. They're different from C++. But they're unique to PHP. This is just something you have to memorize about the language.
I admit the docs could better spell this out, however.
Rule: private
and final
methods on an object will always be called directly, without consulting the override table.
This rule is baked into the engine:
/* Check if this calls a known method on $this */
if (opline->op1_type == IS_UNUSED && opline->op2_type == IS_CONST &&
CG(active_class_entry) && zend_is_scope_known())
zend_string *lcname = Z_STR_P(CT_CONSTANT(opline->op2) + 1);
fbc = zend_hash_find_ptr(&CG(active_class_entry)->function_table, lcname);
/* We only know the exact method that is being called if it is either private or final.
* Otherwise an overriding method in a child class may be called. */
if (fbc && !(fbc->common.fn_flags & (ZEND_ACC_PRIVATE
"Why", you ask? The answer is: because that's how it works. In language design, this is called "name hiding", and it's up to the language to specify how name hiding works. Take C++ for example. It has well-defined, and complex name hiding rules. PHP has its own rules. They're different from C++. But they're unique to PHP. This is just something you have to memorize about the language.
I admit the docs could better spell this out, however.
edited 27 mins ago
answered 37 mins ago
bishop
22.7k46086
22.7k46086
add a comment |Â
add a comment |Â
up vote
2
down vote
This is the behavior in most languages (by design).
If a method is private
, $this->method()
will call it directly (ignore the derived class's method)
If a method is virtual
(this concept comes from C++, in PHP and Java, all public/protected methods are virtual
), $this->method()
will call the derived class's method.
Rule is rule, it is an OOP concern. For example, in OOP we may want to make sure a method never got overridden, then we can make it private
. If a developer overrides it by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation. Thanks to @deceze
Is there an "official" reasoning for this? What I'd cobble together as an explanation would be something like: child classes should not be aware of the existence ofprivate
methods, if they override them it would be by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation�
â decezeâ¦
2 hours ago
Thanks. you just remind me something and it's explained in the office doc. It has the same explanation as yours. the private method has higher precedence.
â Nero
2 hours ago
@deceze yes, it is the OOP concern. I agree with your explanation
â shawn
2 hours ago
My English is not very good, maybe you can help to edit the answer :) @deceze
â shawn
2 hours ago
1
@deceze Yes, there is an official reason...
â bishop
17 mins ago
 |Â
show 1 more comment
up vote
2
down vote
This is the behavior in most languages (by design).
If a method is private
, $this->method()
will call it directly (ignore the derived class's method)
If a method is virtual
(this concept comes from C++, in PHP and Java, all public/protected methods are virtual
), $this->method()
will call the derived class's method.
Rule is rule, it is an OOP concern. For example, in OOP we may want to make sure a method never got overridden, then we can make it private
. If a developer overrides it by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation. Thanks to @deceze
Is there an "official" reasoning for this? What I'd cobble together as an explanation would be something like: child classes should not be aware of the existence ofprivate
methods, if they override them it would be by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation�
â decezeâ¦
2 hours ago
Thanks. you just remind me something and it's explained in the office doc. It has the same explanation as yours. the private method has higher precedence.
â Nero
2 hours ago
@deceze yes, it is the OOP concern. I agree with your explanation
â shawn
2 hours ago
My English is not very good, maybe you can help to edit the answer :) @deceze
â shawn
2 hours ago
1
@deceze Yes, there is an official reason...
â bishop
17 mins ago
 |Â
show 1 more comment
up vote
2
down vote
up vote
2
down vote
This is the behavior in most languages (by design).
If a method is private
, $this->method()
will call it directly (ignore the derived class's method)
If a method is virtual
(this concept comes from C++, in PHP and Java, all public/protected methods are virtual
), $this->method()
will call the derived class's method.
Rule is rule, it is an OOP concern. For example, in OOP we may want to make sure a method never got overridden, then we can make it private
. If a developer overrides it by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation. Thanks to @deceze
This is the behavior in most languages (by design).
If a method is private
, $this->method()
will call it directly (ignore the derived class's method)
If a method is virtual
(this concept comes from C++, in PHP and Java, all public/protected methods are virtual
), $this->method()
will call the derived class's method.
Rule is rule, it is an OOP concern. For example, in OOP we may want to make sure a method never got overridden, then we can make it private
. If a developer overrides it by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation. Thanks to @deceze
edited 2 hours ago
answered 2 hours ago
shawn
2,475616
2,475616
Is there an "official" reasoning for this? What I'd cobble together as an explanation would be something like: child classes should not be aware of the existence ofprivate
methods, if they override them it would be by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation�
â decezeâ¦
2 hours ago
Thanks. you just remind me something and it's explained in the office doc. It has the same explanation as yours. the private method has higher precedence.
â Nero
2 hours ago
@deceze yes, it is the OOP concern. I agree with your explanation
â shawn
2 hours ago
My English is not very good, maybe you can help to edit the answer :) @deceze
â shawn
2 hours ago
1
@deceze Yes, there is an official reason...
â bishop
17 mins ago
 |Â
show 1 more comment
Is there an "official" reasoning for this? What I'd cobble together as an explanation would be something like: child classes should not be aware of the existence ofprivate
methods, if they override them it would be by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation�
â decezeâ¦
2 hours ago
Thanks. you just remind me something and it's explained in the office doc. It has the same explanation as yours. the private method has higher precedence.
â Nero
2 hours ago
@deceze yes, it is the OOP concern. I agree with your explanation
â shawn
2 hours ago
My English is not very good, maybe you can help to edit the answer :) @deceze
â shawn
2 hours ago
1
@deceze Yes, there is an official reason...
â bishop
17 mins ago
Is there an "official" reasoning for this? What I'd cobble together as an explanation would be something like: child classes should not be aware of the existence of
private
methods, if they override them it would be by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementationâ¦?â decezeâ¦
2 hours ago
Is there an "official" reasoning for this? What I'd cobble together as an explanation would be something like: child classes should not be aware of the existence of
private
methods, if they override them it would be by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementationâ¦?â decezeâ¦
2 hours ago
Thanks. you just remind me something and it's explained in the office doc. It has the same explanation as yours. the private method has higher precedence.
â Nero
2 hours ago
Thanks. you just remind me something and it's explained in the office doc. It has the same explanation as yours. the private method has higher precedence.
â Nero
2 hours ago
@deceze yes, it is the OOP concern. I agree with your explanation
â shawn
2 hours ago
@deceze yes, it is the OOP concern. I agree with your explanation
â shawn
2 hours ago
My English is not very good, maybe you can help to edit the answer :) @deceze
â shawn
2 hours ago
My English is not very good, maybe you can help to edit the answer :) @deceze
â shawn
2 hours ago
1
1
@deceze Yes, there is an official reason...
â bishop
17 mins ago
@deceze Yes, there is an official reason...
â bishop
17 mins ago
 |Â
show 1 more comment
up vote
1
down vote
I think the answer lies on the official documentation. doc here
In non-static contexts, the called class will be the class of the object instance. Since $this-> will try to call private methods from the same scope
As a note, though this could eliminate my confusion, simply saying "that is the way it is" seem not enough. Because it's weird behavior. It's not as clear as the late static binding nor respect to the called scope class C (which can be verified using get_called_class() in test() method ).
Yes, this is the documented reason, but I feel it could be clarified. As unsatisfying as it may sound, that's just the way it is. :)
â bishop
18 mins ago
add a comment |Â
up vote
1
down vote
I think the answer lies on the official documentation. doc here
In non-static contexts, the called class will be the class of the object instance. Since $this-> will try to call private methods from the same scope
As a note, though this could eliminate my confusion, simply saying "that is the way it is" seem not enough. Because it's weird behavior. It's not as clear as the late static binding nor respect to the called scope class C (which can be verified using get_called_class() in test() method ).
Yes, this is the documented reason, but I feel it could be clarified. As unsatisfying as it may sound, that's just the way it is. :)
â bishop
18 mins ago
add a comment |Â
up vote
1
down vote
up vote
1
down vote
I think the answer lies on the official documentation. doc here
In non-static contexts, the called class will be the class of the object instance. Since $this-> will try to call private methods from the same scope
As a note, though this could eliminate my confusion, simply saying "that is the way it is" seem not enough. Because it's weird behavior. It's not as clear as the late static binding nor respect to the called scope class C (which can be verified using get_called_class() in test() method ).
I think the answer lies on the official documentation. doc here
In non-static contexts, the called class will be the class of the object instance. Since $this-> will try to call private methods from the same scope
As a note, though this could eliminate my confusion, simply saying "that is the way it is" seem not enough. Because it's weird behavior. It's not as clear as the late static binding nor respect to the called scope class C (which can be verified using get_called_class() in test() method ).
edited 1 hour ago
answered 2 hours ago
Nero
587312
587312
Yes, this is the documented reason, but I feel it could be clarified. As unsatisfying as it may sound, that's just the way it is. :)
â bishop
18 mins ago
add a comment |Â
Yes, this is the documented reason, but I feel it could be clarified. As unsatisfying as it may sound, that's just the way it is. :)
â bishop
18 mins ago
Yes, this is the documented reason, but I feel it could be clarified. As unsatisfying as it may sound, that's just the way it is. :)
â bishop
18 mins ago
Yes, this is the documented reason, but I feel it could be clarified. As unsatisfying as it may sound, that's just the way it is. :)
â bishop
18 mins ago
add a comment |Â
up vote
1
down vote
Ok let me try [Again]
Basically both methods exist side by side.
Private by design means that this thing (method or property) is not visible or accessible or writable by anything besides the class it was defined in. So children cannot use it in any way nor modify it in any way. This is the behaviour of private.
The why (the reason) behind the concept, is to guarantee a specific functionality (or value, of properties) no matter how the class is extended. This is good because when designing the Parent class we may not know how it will be used by any extending classes, and there may be functionality that is critical and should not be changed. This gives us a way to guarantee that in our code without knowing the implementation of the children.
One reason they can exist side by side, is inside of the child class when you call $this->foo()
there is no ambiguity about which foo is being called as only the public version C::foo()
visible to class C
(the child) class.
class A
private function foo()
echo "A!";
public function parentTest()
//if we used C::foo() from here Overriding A::foo().
//having a concept of private would lose all meaning
//because we would be allowing the child to modify it
$this->foo();
class C extends A
public function foo()
echo 'C!';
public function childTest()
//A::foo() cannot be used from here
//so PHP knows to use C::foo()
$this->foo();
In short there is only one Foo available to the child class C::foo()
, so there is no way it can be confused with the private version A::foo()
by PHP. In this way both methods can exist without the child overriding the parents method.
Don't let me confuse you more here, because in some ways the childs method does override the parents. We can see this if we call $obj->foo()
from the global space. If we don't define foo in the child C
then we get an error. But if we do define a public one in C
it is used. Another thing that shows that it does overwrite (in some ways) is if we set the parent's copy A::foo()
to be final. In this case if we try to define C::foo()
we get an error as we would expect.
But (here is the important part), neither of these affect the functionality of the private stuff as far as the parent is concerned and so they do not violate the private principle.
Now for the parents call to its own private method.
This is where most people get confused and you asked:
When calling what is for all intents and purposes C::test, why does it prefer the private A::foo over the public C::foo
It doesn't because you are calling the private method from another method in the same class where the private one was defined.
If it preferred the child's method, then then there would be no point in having a private visibility because we would have just violated it by allowing the child to modify the method. In other words we would be using the child's functionality instead of that marked by private.
I will try to say the same things in a different way, maybe that will help (or it will just confuse you more...lol).
The reason you can have another method with the same name and it's own functionality (something I really don't care for and avoid) is because the parents private functionality does not enter the scope of the child class, so there is no way for PHP to get confused about what version private or public to use. It knows to use the public if not in the class it was defined in but to use the private if it is in the class it was defined in.
I hope that helps, that's the best I can do.
When calling what is for all intents and purposesC::test
, why does it prefer theprivate
A::foo
over thepublic
C::foo
?
â decezeâ¦
2 hours ago
It doesn't prefer it. Your thinking in terms of it over writing or replacing that method, which it doesn't do. It simply doesn't exist.
â ArtisticPhoenix
1 hour ago
1
Explanation like class A does not know about existence of class B seem make no sense to me especially when we're talking with my example. the way you try to prove this is wrong, because you use (new A)->test(); but in my case, it's (new C)->test(); They are different. You call parent directly and of course it won't know. In my case, it makes call from a child. Correct me if wrong.
â Nero
1 hour ago
1
Additionally, if you remove function foo() from class A, the one defined in child will be called. Dose this prove "class A is aware of class C's existence" ?
â Nero
1 hour ago
Dose this prove "class A is aware of class C's existence"
No because your calling it from an instance of the child. And even though you call the private method from an child instance private overrides that normal behaviour. If it didn't there would be no point in having it.
â ArtisticPhoenix
55 mins ago
 |Â
show 1 more comment
up vote
1
down vote
Ok let me try [Again]
Basically both methods exist side by side.
Private by design means that this thing (method or property) is not visible or accessible or writable by anything besides the class it was defined in. So children cannot use it in any way nor modify it in any way. This is the behaviour of private.
The why (the reason) behind the concept, is to guarantee a specific functionality (or value, of properties) no matter how the class is extended. This is good because when designing the Parent class we may not know how it will be used by any extending classes, and there may be functionality that is critical and should not be changed. This gives us a way to guarantee that in our code without knowing the implementation of the children.
One reason they can exist side by side, is inside of the child class when you call $this->foo()
there is no ambiguity about which foo is being called as only the public version C::foo()
visible to class C
(the child) class.
class A
private function foo()
echo "A!";
public function parentTest()
//if we used C::foo() from here Overriding A::foo().
//having a concept of private would lose all meaning
//because we would be allowing the child to modify it
$this->foo();
class C extends A
public function foo()
echo 'C!';
public function childTest()
//A::foo() cannot be used from here
//so PHP knows to use C::foo()
$this->foo();
In short there is only one Foo available to the child class C::foo()
, so there is no way it can be confused with the private version A::foo()
by PHP. In this way both methods can exist without the child overriding the parents method.
Don't let me confuse you more here, because in some ways the childs method does override the parents. We can see this if we call $obj->foo()
from the global space. If we don't define foo in the child C
then we get an error. But if we do define a public one in C
it is used. Another thing that shows that it does overwrite (in some ways) is if we set the parent's copy A::foo()
to be final. In this case if we try to define C::foo()
we get an error as we would expect.
But (here is the important part), neither of these affect the functionality of the private stuff as far as the parent is concerned and so they do not violate the private principle.
Now for the parents call to its own private method.
This is where most people get confused and you asked:
When calling what is for all intents and purposes C::test, why does it prefer the private A::foo over the public C::foo
It doesn't because you are calling the private method from another method in the same class where the private one was defined.
If it preferred the child's method, then then there would be no point in having a private visibility because we would have just violated it by allowing the child to modify the method. In other words we would be using the child's functionality instead of that marked by private.
I will try to say the same things in a different way, maybe that will help (or it will just confuse you more...lol).
The reason you can have another method with the same name and it's own functionality (something I really don't care for and avoid) is because the parents private functionality does not enter the scope of the child class, so there is no way for PHP to get confused about what version private or public to use. It knows to use the public if not in the class it was defined in but to use the private if it is in the class it was defined in.
I hope that helps, that's the best I can do.
When calling what is for all intents and purposesC::test
, why does it prefer theprivate
A::foo
over thepublic
C::foo
?
â decezeâ¦
2 hours ago
It doesn't prefer it. Your thinking in terms of it over writing or replacing that method, which it doesn't do. It simply doesn't exist.
â ArtisticPhoenix
1 hour ago
1
Explanation like class A does not know about existence of class B seem make no sense to me especially when we're talking with my example. the way you try to prove this is wrong, because you use (new A)->test(); but in my case, it's (new C)->test(); They are different. You call parent directly and of course it won't know. In my case, it makes call from a child. Correct me if wrong.
â Nero
1 hour ago
1
Additionally, if you remove function foo() from class A, the one defined in child will be called. Dose this prove "class A is aware of class C's existence" ?
â Nero
1 hour ago
Dose this prove "class A is aware of class C's existence"
No because your calling it from an instance of the child. And even though you call the private method from an child instance private overrides that normal behaviour. If it didn't there would be no point in having it.
â ArtisticPhoenix
55 mins ago
 |Â
show 1 more comment
up vote
1
down vote
up vote
1
down vote
Ok let me try [Again]
Basically both methods exist side by side.
Private by design means that this thing (method or property) is not visible or accessible or writable by anything besides the class it was defined in. So children cannot use it in any way nor modify it in any way. This is the behaviour of private.
The why (the reason) behind the concept, is to guarantee a specific functionality (or value, of properties) no matter how the class is extended. This is good because when designing the Parent class we may not know how it will be used by any extending classes, and there may be functionality that is critical and should not be changed. This gives us a way to guarantee that in our code without knowing the implementation of the children.
One reason they can exist side by side, is inside of the child class when you call $this->foo()
there is no ambiguity about which foo is being called as only the public version C::foo()
visible to class C
(the child) class.
class A
private function foo()
echo "A!";
public function parentTest()
//if we used C::foo() from here Overriding A::foo().
//having a concept of private would lose all meaning
//because we would be allowing the child to modify it
$this->foo();
class C extends A
public function foo()
echo 'C!';
public function childTest()
//A::foo() cannot be used from here
//so PHP knows to use C::foo()
$this->foo();
In short there is only one Foo available to the child class C::foo()
, so there is no way it can be confused with the private version A::foo()
by PHP. In this way both methods can exist without the child overriding the parents method.
Don't let me confuse you more here, because in some ways the childs method does override the parents. We can see this if we call $obj->foo()
from the global space. If we don't define foo in the child C
then we get an error. But if we do define a public one in C
it is used. Another thing that shows that it does overwrite (in some ways) is if we set the parent's copy A::foo()
to be final. In this case if we try to define C::foo()
we get an error as we would expect.
But (here is the important part), neither of these affect the functionality of the private stuff as far as the parent is concerned and so they do not violate the private principle.
Now for the parents call to its own private method.
This is where most people get confused and you asked:
When calling what is for all intents and purposes C::test, why does it prefer the private A::foo over the public C::foo
It doesn't because you are calling the private method from another method in the same class where the private one was defined.
If it preferred the child's method, then then there would be no point in having a private visibility because we would have just violated it by allowing the child to modify the method. In other words we would be using the child's functionality instead of that marked by private.
I will try to say the same things in a different way, maybe that will help (or it will just confuse you more...lol).
The reason you can have another method with the same name and it's own functionality (something I really don't care for and avoid) is because the parents private functionality does not enter the scope of the child class, so there is no way for PHP to get confused about what version private or public to use. It knows to use the public if not in the class it was defined in but to use the private if it is in the class it was defined in.
I hope that helps, that's the best I can do.
Ok let me try [Again]
Basically both methods exist side by side.
Private by design means that this thing (method or property) is not visible or accessible or writable by anything besides the class it was defined in. So children cannot use it in any way nor modify it in any way. This is the behaviour of private.
The why (the reason) behind the concept, is to guarantee a specific functionality (or value, of properties) no matter how the class is extended. This is good because when designing the Parent class we may not know how it will be used by any extending classes, and there may be functionality that is critical and should not be changed. This gives us a way to guarantee that in our code without knowing the implementation of the children.
One reason they can exist side by side, is inside of the child class when you call $this->foo()
there is no ambiguity about which foo is being called as only the public version C::foo()
visible to class C
(the child) class.
class A
private function foo()
echo "A!";
public function parentTest()
//if we used C::foo() from here Overriding A::foo().
//having a concept of private would lose all meaning
//because we would be allowing the child to modify it
$this->foo();
class C extends A
public function foo()
echo 'C!';
public function childTest()
//A::foo() cannot be used from here
//so PHP knows to use C::foo()
$this->foo();
In short there is only one Foo available to the child class C::foo()
, so there is no way it can be confused with the private version A::foo()
by PHP. In this way both methods can exist without the child overriding the parents method.
Don't let me confuse you more here, because in some ways the childs method does override the parents. We can see this if we call $obj->foo()
from the global space. If we don't define foo in the child C
then we get an error. But if we do define a public one in C
it is used. Another thing that shows that it does overwrite (in some ways) is if we set the parent's copy A::foo()
to be final. In this case if we try to define C::foo()
we get an error as we would expect.
But (here is the important part), neither of these affect the functionality of the private stuff as far as the parent is concerned and so they do not violate the private principle.
Now for the parents call to its own private method.
This is where most people get confused and you asked:
When calling what is for all intents and purposes C::test, why does it prefer the private A::foo over the public C::foo
It doesn't because you are calling the private method from another method in the same class where the private one was defined.
If it preferred the child's method, then then there would be no point in having a private visibility because we would have just violated it by allowing the child to modify the method. In other words we would be using the child's functionality instead of that marked by private.
I will try to say the same things in a different way, maybe that will help (or it will just confuse you more...lol).
The reason you can have another method with the same name and it's own functionality (something I really don't care for and avoid) is because the parents private functionality does not enter the scope of the child class, so there is no way for PHP to get confused about what version private or public to use. It knows to use the public if not in the class it was defined in but to use the private if it is in the class it was defined in.
I hope that helps, that's the best I can do.
edited 53 secs ago
answered 2 hours ago
ArtisticPhoenix
14.4k11223
14.4k11223
When calling what is for all intents and purposesC::test
, why does it prefer theprivate
A::foo
over thepublic
C::foo
?
â decezeâ¦
2 hours ago
It doesn't prefer it. Your thinking in terms of it over writing or replacing that method, which it doesn't do. It simply doesn't exist.
â ArtisticPhoenix
1 hour ago
1
Explanation like class A does not know about existence of class B seem make no sense to me especially when we're talking with my example. the way you try to prove this is wrong, because you use (new A)->test(); but in my case, it's (new C)->test(); They are different. You call parent directly and of course it won't know. In my case, it makes call from a child. Correct me if wrong.
â Nero
1 hour ago
1
Additionally, if you remove function foo() from class A, the one defined in child will be called. Dose this prove "class A is aware of class C's existence" ?
â Nero
1 hour ago
Dose this prove "class A is aware of class C's existence"
No because your calling it from an instance of the child. And even though you call the private method from an child instance private overrides that normal behaviour. If it didn't there would be no point in having it.
â ArtisticPhoenix
55 mins ago
 |Â
show 1 more comment
When calling what is for all intents and purposesC::test
, why does it prefer theprivate
A::foo
over thepublic
C::foo
?
â decezeâ¦
2 hours ago
It doesn't prefer it. Your thinking in terms of it over writing or replacing that method, which it doesn't do. It simply doesn't exist.
â ArtisticPhoenix
1 hour ago
1
Explanation like class A does not know about existence of class B seem make no sense to me especially when we're talking with my example. the way you try to prove this is wrong, because you use (new A)->test(); but in my case, it's (new C)->test(); They are different. You call parent directly and of course it won't know. In my case, it makes call from a child. Correct me if wrong.
â Nero
1 hour ago
1
Additionally, if you remove function foo() from class A, the one defined in child will be called. Dose this prove "class A is aware of class C's existence" ?
â Nero
1 hour ago
Dose this prove "class A is aware of class C's existence"
No because your calling it from an instance of the child. And even though you call the private method from an child instance private overrides that normal behaviour. If it didn't there would be no point in having it.
â ArtisticPhoenix
55 mins ago
When calling what is for all intents and purposes
C::test
, why does it prefer the private
A::foo
over the public
C::foo
?â decezeâ¦
2 hours ago
When calling what is for all intents and purposes
C::test
, why does it prefer the private
A::foo
over the public
C::foo
?â decezeâ¦
2 hours ago
It doesn't prefer it. Your thinking in terms of it over writing or replacing that method, which it doesn't do. It simply doesn't exist.
â ArtisticPhoenix
1 hour ago
It doesn't prefer it. Your thinking in terms of it over writing or replacing that method, which it doesn't do. It simply doesn't exist.
â ArtisticPhoenix
1 hour ago
1
1
Explanation like class A does not know about existence of class B seem make no sense to me especially when we're talking with my example. the way you try to prove this is wrong, because you use (new A)->test(); but in my case, it's (new C)->test(); They are different. You call parent directly and of course it won't know. In my case, it makes call from a child. Correct me if wrong.
â Nero
1 hour ago
Explanation like class A does not know about existence of class B seem make no sense to me especially when we're talking with my example. the way you try to prove this is wrong, because you use (new A)->test(); but in my case, it's (new C)->test(); They are different. You call parent directly and of course it won't know. In my case, it makes call from a child. Correct me if wrong.
â Nero
1 hour ago
1
1
Additionally, if you remove function foo() from class A, the one defined in child will be called. Dose this prove "class A is aware of class C's existence" ?
â Nero
1 hour ago
Additionally, if you remove function foo() from class A, the one defined in child will be called. Dose this prove "class A is aware of class C's existence" ?
â Nero
1 hour ago
Dose this prove "class A is aware of class C's existence"
No because your calling it from an instance of the child. And even though you call the private method from an child instance private overrides that normal behaviour. If it didn't there would be no point in having it.â ArtisticPhoenix
55 mins ago
Dose this prove "class A is aware of class C's existence"
No because your calling it from an instance of the child. And even though you call the private method from an child instance private overrides that normal behaviour. If it didn't there would be no point in having it.â ArtisticPhoenix
55 mins ago
 |Â
show 1 more comment
up vote
0
down vote
Because in first case you are not overriding the foo() in derived class C, because foo() is private.
But, in case two, foo() is public and is overridden by function foo() in class C
So, by basics of inheritance you can't override a private method and hence your foo() in class C has no existence in first case (keeping or deleting it does not matter) and the actual method of extended class A will be called since you have no right to override it in your class.
Try this:
public function test()
echo get_class($this);
$this->foo();
In both case it will echo C , not A. So, $this is object of C which cannot override private methods of A, hence foo() of C has no use when foo() exists in class A and is private.
New contributor
Your last paragraph underscores the reason for the confusion, I think, and your earlier paragraphs don't help clarify that confusion, in my opinion. If in both cases the object$this
is ofclass C
, then there's a reasonable expectation thatC::foo()
will be called regardless of the existence ofA::foo()
. However, the OP demonstrates that's not the case and wants to know why. The answer, as it turns out, cannot be explained by rationalization based on inheritance -- it's simply a rule the engine implements, and it must be memorized.
â bishop
23 mins ago
add a comment |Â
up vote
0
down vote
Because in first case you are not overriding the foo() in derived class C, because foo() is private.
But, in case two, foo() is public and is overridden by function foo() in class C
So, by basics of inheritance you can't override a private method and hence your foo() in class C has no existence in first case (keeping or deleting it does not matter) and the actual method of extended class A will be called since you have no right to override it in your class.
Try this:
public function test()
echo get_class($this);
$this->foo();
In both case it will echo C , not A. So, $this is object of C which cannot override private methods of A, hence foo() of C has no use when foo() exists in class A and is private.
New contributor
Your last paragraph underscores the reason for the confusion, I think, and your earlier paragraphs don't help clarify that confusion, in my opinion. If in both cases the object$this
is ofclass C
, then there's a reasonable expectation thatC::foo()
will be called regardless of the existence ofA::foo()
. However, the OP demonstrates that's not the case and wants to know why. The answer, as it turns out, cannot be explained by rationalization based on inheritance -- it's simply a rule the engine implements, and it must be memorized.
â bishop
23 mins ago
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Because in first case you are not overriding the foo() in derived class C, because foo() is private.
But, in case two, foo() is public and is overridden by function foo() in class C
So, by basics of inheritance you can't override a private method and hence your foo() in class C has no existence in first case (keeping or deleting it does not matter) and the actual method of extended class A will be called since you have no right to override it in your class.
Try this:
public function test()
echo get_class($this);
$this->foo();
In both case it will echo C , not A. So, $this is object of C which cannot override private methods of A, hence foo() of C has no use when foo() exists in class A and is private.
New contributor
Because in first case you are not overriding the foo() in derived class C, because foo() is private.
But, in case two, foo() is public and is overridden by function foo() in class C
So, by basics of inheritance you can't override a private method and hence your foo() in class C has no existence in first case (keeping or deleting it does not matter) and the actual method of extended class A will be called since you have no right to override it in your class.
Try this:
public function test()
echo get_class($this);
$this->foo();
In both case it will echo C , not A. So, $this is object of C which cannot override private methods of A, hence foo() of C has no use when foo() exists in class A and is private.
New contributor
edited 38 mins ago
New contributor
answered 1 hour ago
Manpreet
163
163
New contributor
New contributor
Your last paragraph underscores the reason for the confusion, I think, and your earlier paragraphs don't help clarify that confusion, in my opinion. If in both cases the object$this
is ofclass C
, then there's a reasonable expectation thatC::foo()
will be called regardless of the existence ofA::foo()
. However, the OP demonstrates that's not the case and wants to know why. The answer, as it turns out, cannot be explained by rationalization based on inheritance -- it's simply a rule the engine implements, and it must be memorized.
â bishop
23 mins ago
add a comment |Â
Your last paragraph underscores the reason for the confusion, I think, and your earlier paragraphs don't help clarify that confusion, in my opinion. If in both cases the object$this
is ofclass C
, then there's a reasonable expectation thatC::foo()
will be called regardless of the existence ofA::foo()
. However, the OP demonstrates that's not the case and wants to know why. The answer, as it turns out, cannot be explained by rationalization based on inheritance -- it's simply a rule the engine implements, and it must be memorized.
â bishop
23 mins ago
Your last paragraph underscores the reason for the confusion, I think, and your earlier paragraphs don't help clarify that confusion, in my opinion. If in both cases the object
$this
is of class C
, then there's a reasonable expectation that C::foo()
will be called regardless of the existence of A::foo()
. However, the OP demonstrates that's not the case and wants to know why. The answer, as it turns out, cannot be explained by rationalization based on inheritance -- it's simply a rule the engine implements, and it must be memorized.â bishop
23 mins ago
Your last paragraph underscores the reason for the confusion, I think, and your earlier paragraphs don't help clarify that confusion, in my opinion. If in both cases the object
$this
is of class C
, then there's a reasonable expectation that C::foo()
will be called regardless of the existence of A::foo()
. However, the OP demonstrates that's not the case and wants to know why. The answer, as it turns out, cannot be explained by rationalization based on inheritance -- it's simply a rule the engine implements, and it must be memorized.â bishop
23 mins ago
add a comment |Â
up vote
0
down vote
Private foo() is a part of class A, and A does not know about the existence of the C class. It can work without it.
When extending A class, C inherits all public and protected method of A, that's why test() is available. You would call the private foo() method of A class from within the test() method, not the one from C. Extending works in one direction only, you would not be able to call methods from C from within A. A can be instantiated without C and nothing can guarantee another class will extend it.
A does not know about the existence of the C class, but why after change visibility of foo method in class A make it know about the existence of the C class?
â Nero
1 hour ago
"Extending works in one direction only". Does it? The second scenario in the OP is an example whereA::test()
callsC::foo()
.
â bishop
15 mins ago
add a comment |Â
up vote
0
down vote
Private foo() is a part of class A, and A does not know about the existence of the C class. It can work without it.
When extending A class, C inherits all public and protected method of A, that's why test() is available. You would call the private foo() method of A class from within the test() method, not the one from C. Extending works in one direction only, you would not be able to call methods from C from within A. A can be instantiated without C and nothing can guarantee another class will extend it.
A does not know about the existence of the C class, but why after change visibility of foo method in class A make it know about the existence of the C class?
â Nero
1 hour ago
"Extending works in one direction only". Does it? The second scenario in the OP is an example whereA::test()
callsC::foo()
.
â bishop
15 mins ago
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Private foo() is a part of class A, and A does not know about the existence of the C class. It can work without it.
When extending A class, C inherits all public and protected method of A, that's why test() is available. You would call the private foo() method of A class from within the test() method, not the one from C. Extending works in one direction only, you would not be able to call methods from C from within A. A can be instantiated without C and nothing can guarantee another class will extend it.
Private foo() is a part of class A, and A does not know about the existence of the C class. It can work without it.
When extending A class, C inherits all public and protected method of A, that's why test() is available. You would call the private foo() method of A class from within the test() method, not the one from C. Extending works in one direction only, you would not be able to call methods from C from within A. A can be instantiated without C and nothing can guarantee another class will extend it.
edited 16 mins ago
bishop
22.7k46086
22.7k46086
answered 2 hours ago
Marius S
146113
146113
A does not know about the existence of the C class, but why after change visibility of foo method in class A make it know about the existence of the C class?
â Nero
1 hour ago
"Extending works in one direction only". Does it? The second scenario in the OP is an example whereA::test()
callsC::foo()
.
â bishop
15 mins ago
add a comment |Â
A does not know about the existence of the C class, but why after change visibility of foo method in class A make it know about the existence of the C class?
â Nero
1 hour ago
"Extending works in one direction only". Does it? The second scenario in the OP is an example whereA::test()
callsC::foo()
.
â bishop
15 mins ago
A does not know about the existence of the C class, but why after change visibility of foo method in class A make it know about the existence of the C class?
â Nero
1 hour ago
A does not know about the existence of the C class, but why after change visibility of foo method in class A make it know about the existence of the C class?
â Nero
1 hour ago
"Extending works in one direction only". Does it? The second scenario in the OP is an example where
A::test()
calls C::foo()
.â bishop
15 mins ago
"Extending works in one direction only". Does it? The second scenario in the OP is an example where
A::test()
calls C::foo()
.â bishop
15 mins ago
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53111792%2fphp-method-scope-binding%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Private methods are only visible to the actual class, protected is visible only inside the class (any child class). Public is for the world to see. In your fist example calling
foo
will fail in any case except from within the class it's defined within. When you override foo in the child, it doesn't replace the private foo method because it's not visible to the C class at all.â ArtisticPhoenix
2 hours ago
3
@ArtisticPhoenix thanks for comment, but I don't think that solve my confusion. Maybe you can explain in more details using above example.
â Nero
2 hours ago
@Artistic
foo
is only called from within the class that defines it. The question is whytest
sticks to callingA::foo
instead ofC::foo
.â decezeâ¦
2 hours ago
I tried, it's like relativity it's all depends on the reference frame of the observer. You can't think of it in terms of the Global space (space outside the classes).
â ArtisticPhoenix
38 mins ago