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
2
@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â¦
1 hour 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
20 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 1 hour 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
2
@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â¦
1 hour 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
20 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
2
@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â¦
1 hour 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
20 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
2
2
@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â¦
1 hour 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â¦
1 hour 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
20 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
20 mins ago
add a comment |Â
6 Answers
6
active
oldest
votes
up vote
3
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_ACC_FINAL)))
fbc = NULL;
"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
1
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â¦
1 hour 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
1 hour ago
@deceze yes, it is the OOP concern. I agree with your explanation
â shawn
1 hour ago
My English is not very good, maybe you can help to edit the answer :) @deceze
â shawn
1 hour 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
1 min 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 classes of it, 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
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
6 mins ago
add a comment |Â
up vote
0
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 viable or overwriteable by a descendant object.
The 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 is visible to this class, in this case. You could make it private in the child and only that one would be visible to it. Also you could have a class between the parent and child with it's public method and no method in the last child and he would see the last public method defined. In shot there is only one Foo available to the child class, so there is no way it can be confused with the private version.
Now from the parents call to its own private method. This is where most people get confused. 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 didn't call the private method but instead called the child method from the method in the parent, that would completely defeat the reason for private. And, it would lose any value it has. In essence it would be meaningless and we wouldn't be discussing the finer points of it.
When calling what is for all intents and purposesC::test
, why does it prefer theprivate
A::foo
over thepublic
C::foo
?
â decezeâ¦
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
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
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
38 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
3
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_ACC_FINAL)))
fbc = NULL;
"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
3
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_ACC_FINAL)))
fbc = NULL;
"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
3
down vote
accepted
up vote
3
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_ACC_FINAL)))
fbc = NULL;
"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_ACC_FINAL)))
fbc = NULL;
"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 10 mins ago
answered 19 mins ago
bishop
22.7k46086
22.7k46086
add a comment |Â
add a comment |Â
up vote
1
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â¦
1 hour 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
1 hour ago
@deceze yes, it is the OOP concern. I agree with your explanation
â shawn
1 hour ago
My English is not very good, maybe you can help to edit the answer :) @deceze
â shawn
1 hour ago
add a comment |Â
up vote
1
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â¦
1 hour 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
1 hour ago
@deceze yes, it is the OOP concern. I agree with your explanation
â shawn
1 hour ago
My English is not very good, maybe you can help to edit the answer :) @deceze
â shawn
1 hour ago
add a comment |Â
up vote
1
down vote
up vote
1
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 1 hour ago
answered 1 hour ago
shawn
2,465616
2,465616
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â¦
1 hour 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
1 hour ago
@deceze yes, it is the OOP concern. I agree with your explanation
â shawn
1 hour ago
My English is not very good, maybe you can help to edit the answer :) @deceze
â shawn
1 hour ago
add a 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â¦
1 hour 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
1 hour ago
@deceze yes, it is the OOP concern. I agree with your explanation
â shawn
1 hour ago
My English is not very good, maybe you can help to edit the answer :) @deceze
â shawn
1 hour 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â¦
1 hour 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â¦
1 hour 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
1 hour 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
1 hour ago
@deceze yes, it is the OOP concern. I agree with your explanation
â shawn
1 hour ago
@deceze yes, it is the OOP concern. I agree with your explanation
â shawn
1 hour ago
My English is not very good, maybe you can help to edit the answer :) @deceze
â shawn
1 hour ago
My English is not very good, maybe you can help to edit the answer :) @deceze
â shawn
1 hour 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
1 min 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
1 min 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 1 hour 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
1 min 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
1 min 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
1 min 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
1 min 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 classes of it, 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
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 classes of it, 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
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 classes of it, 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 classes of it, 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.
answered 1 hour 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
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
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
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
6 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
6 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 21 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
6 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
6 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
6 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
6 mins ago
add a comment |Â
up vote
0
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 viable or overwriteable by a descendant object.
The 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 is visible to this class, in this case. You could make it private in the child and only that one would be visible to it. Also you could have a class between the parent and child with it's public method and no method in the last child and he would see the last public method defined. In shot there is only one Foo available to the child class, so there is no way it can be confused with the private version.
Now from the parents call to its own private method. This is where most people get confused. 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 didn't call the private method but instead called the child method from the method in the parent, that would completely defeat the reason for private. And, it would lose any value it has. In essence it would be meaningless and we wouldn't be discussing the finer points of it.
When calling what is for all intents and purposesC::test
, why does it prefer theprivate
A::foo
over thepublic
C::foo
?
â decezeâ¦
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
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
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
38 mins ago
add a comment |Â
up vote
0
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 viable or overwriteable by a descendant object.
The 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 is visible to this class, in this case. You could make it private in the child and only that one would be visible to it. Also you could have a class between the parent and child with it's public method and no method in the last child and he would see the last public method defined. In shot there is only one Foo available to the child class, so there is no way it can be confused with the private version.
Now from the parents call to its own private method. This is where most people get confused. 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 didn't call the private method but instead called the child method from the method in the parent, that would completely defeat the reason for private. And, it would lose any value it has. In essence it would be meaningless and we wouldn't be discussing the finer points of it.
When calling what is for all intents and purposesC::test
, why does it prefer theprivate
A::foo
over thepublic
C::foo
?
â decezeâ¦
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
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
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
38 mins ago
add a comment |Â
up vote
0
down vote
up vote
0
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 viable or overwriteable by a descendant object.
The 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 is visible to this class, in this case. You could make it private in the child and only that one would be visible to it. Also you could have a class between the parent and child with it's public method and no method in the last child and he would see the last public method defined. In shot there is only one Foo available to the child class, so there is no way it can be confused with the private version.
Now from the parents call to its own private method. This is where most people get confused. 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 didn't call the private method but instead called the child method from the method in the parent, that would completely defeat the reason for private. And, it would lose any value it has. In essence it would be meaningless and we wouldn't be discussing the finer points of it.
Ok let me try [Again]
Basically both methods exist side by side.
Private by design means that this thing (method or property) is not viable or overwriteable by a descendant object.
The 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 is visible to this class, in this case. You could make it private in the child and only that one would be visible to it. Also you could have a class between the parent and child with it's public method and no method in the last child and he would see the last public method defined. In shot there is only one Foo available to the child class, so there is no way it can be confused with the private version.
Now from the parents call to its own private method. This is where most people get confused. 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 didn't call the private method but instead called the child method from the method in the parent, that would completely defeat the reason for private. And, it would lose any value it has. In essence it would be meaningless and we wouldn't be discussing the finer points of it.
edited 13 mins ago
answered 1 hour 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â¦
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
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
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
38 mins ago
add a comment |Â
When calling what is for all intents and purposesC::test
, why does it prefer theprivate
A::foo
over thepublic
C::foo
?
â decezeâ¦
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
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
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
38 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â¦
1 hour 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â¦
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
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
55 mins 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
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
38 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
38 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
2
@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â¦
1 hour 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
20 mins ago