PHP method scope binding

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
6
down vote

favorite
1












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.










share|improve this question























  • 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 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














up vote
6
down vote

favorite
1












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.










share|improve this question























  • 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 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












up vote
6
down vote

favorite
1









up vote
6
down vote

favorite
1






1





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.










share|improve this question















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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 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
















  • 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 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















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












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.






share|improve this answer





























    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






    share|improve this answer






















    • 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










    • @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

















    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 ).






    share|improve this answer






















    • 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

















    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.






    share|improve this answer






















    • 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







    • 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


















    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.






    share|improve this answer










    New contributor




    Manpreet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.

















    • 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


















    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.






    share|improve this answer






















    • 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











    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    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






























    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.






    share|improve this answer


























      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.






      share|improve this answer
























        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.






        share|improve this answer














        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.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 27 mins ago

























        answered 37 mins ago









        bishop

        22.7k46086




        22.7k46086






















            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






            share|improve this answer






















            • 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










            • @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














            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






            share|improve this answer






















            • 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










            • @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












            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






            share|improve this answer














            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







            share|improve this answer














            share|improve this answer



            share|improve this answer








            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 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










            • @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










            • 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










            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 ).






            share|improve this answer






















            • 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














            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 ).






            share|improve this answer






















            • 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












            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 ).






            share|improve this answer














            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 ).







            share|improve this answer














            share|improve this answer



            share|improve this answer








            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
















            • 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










            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.






            share|improve this answer






















            • 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







            • 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















            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.






            share|improve this answer






















            • 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







            • 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













            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.






            share|improve this answer














            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.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 53 secs ago

























            answered 2 hours ago









            ArtisticPhoenix

            14.4k11223




            14.4k11223











            • 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







            • 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











            • 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











            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.






            share|improve this answer










            New contributor




            Manpreet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.

















            • 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















            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.






            share|improve this answer










            New contributor




            Manpreet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.

















            • 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













            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.






            share|improve this answer










            New contributor




            Manpreet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.









            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.







            share|improve this answer










            New contributor




            Manpreet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.









            share|improve this answer



            share|improve this answer








            edited 38 mins ago





















            New contributor




            Manpreet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.









            answered 1 hour ago









            Manpreet

            163




            163




            New contributor




            Manpreet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.





            New contributor





            Manpreet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.






            Manpreet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.











            • 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
















            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











            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.






            share|improve this answer






















            • 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















            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.






            share|improve this answer






















            • 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













            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.






            share|improve this answer














            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.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            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 where A::test() calls C::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










            • "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
















            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


















             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            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













































































            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Displaying single band from multi-band raster using QGIS

            How many registers does an x86_64 CPU actually have?