Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This one is with using static methods</p> <pre><code>&lt;?php class ClassA { function Draw() { echo "DrawA"; /* Drawing code ... */ } function InvokeDraw() { self::Draw(); } } class ClassB extends ClassA { function Draw() { echo "DrawB"; parent::InvokeDraw(); /* Drawing code ... */ } } echo "Begin:&lt;br&gt;"; $cb = new ClassB(); $cb-&gt;Draw(); </code></pre> <p>Note that the only thing I changed is the <code>InvokeDraw()</code> method and made it use <code>self</code> which refers to a class, rather than object as it is with <code>$this</code></p> <p>Output:</p> <pre><code>Begin: DrawBDrawA </code></pre> <p><strong>Edit:</strong> To answer your comment below I will add a short description of how your code works and how this code works.</p> <p>What happens in your code:</p> <ol> <li>We create <code>B</code> and start working with it</li> <li>We call <code>B-&gt;Draw()</code> while working within <code>B</code> class AND <code>B</code> object.</li> <li><code>B-&gt;Draw()</code> calls statically(that means class method) <code>A::Invoke()</code> from class A <strong>BUT</strong> we are still using <code>B</code> object.</li> <li>Static call <code>A::Invoke()</code> calls <code>$this-&gt;Draw();</code> and as we are working currently with <code>B</code> object, <code>$this</code> refers to an instance of <code>ClassB</code>.</li> <li>And here we go looping.</li> </ol> <p>What happens in the code above:</p> <ol> <li>We create <code>B</code> and start working with it</li> <li>We call <code>B-&gt;Draw()</code> while working within <code>B</code> class AND <code>B</code> object.</li> <li><code>B-&gt;Draw()</code> calls statically(that means class method) <code>A::Invoke</code> from class A <strong>BUT</strong> as well as in your code we are still using <code>B</code> object.</li> <li>Static call <code>A::Invoke()</code> calls <code>self::Draw()</code> which is basically the same as <code>ClassA::Draw()</code> and because it's a static method, we don't care what object we are currently working with and we call the <code>A</code>'s <code>Draw()</code> method.</li> <li><code>A::Draw()</code> method executes as we need.</li> </ol> <p>I will provide the same explanation for the code in my second answer, which doesn't use static calls:</p> <ol> <li>We create <code>B</code> and start working with it</li> <li>We call <code>B-&gt;Draw()</code> while working within <code>B</code> class AND <code>B</code> object.</li> <li><code>B-&gt;Draw()</code> <strong>CREATES</strong> an instance of <code>A</code>.</li> <li><code>B-&gt;Draw()</code> calls <code>A-&gt;Invoke()</code> which means we start to work with an object that is instance of class <code>A</code> and not <code>B</code> like before.</li> </ol> <p><em>At this point we completely forget that <code>B</code> even exists and work only with <code>A</code></em></p> <ol> <li><code>A-&gt;Invoke()</code> calls <code>$this-&gt;Draw()</code> which means that we are calling <code>A-&gt;Draw()</code>, because we already work with an instance of class <code>A</code>.</li> <li><code>A-&gt;Draw()</code> executes as we expect.</li> </ol> <p>From usability point of view, we can see that the static method is better, as we can define some static properties and you can work with them when <code>A::Draw()</code> executes. If we use non-static method, then we need to pass the data we need within arguments of our methods.</p> <p>I hope this makes it clear. The sequences above do not have the right terminology, but it was written on purpose, I think it's easier to understand the flow that way.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload