Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
475 views
in Technique[技术] by (71.8m points)

class - Access parent's overridden method from parent's context in PHP

I have a drawing PHP class called ClassA that is extended by many other drawing classes, ClassB for instance.

I need the inherited classes to fire its parent classes' Draw() method. However, in my particular situation, I do not want to call such method directly (e.g.: parent::Draw()). I'd like a third function (e.g.: parent::InvokeDraw()) to call my drawing method from within the parent's context.

Here's some code to illustrate:

class ClassA
{
    function Draw()
    {

        /* Drawing code ... */

    }

    function InvokeDraw()
    {
        $this->Draw();
    }
}


class ClassB extends ClassA
{
    function Draw()
    {
        parent::InvokeDraw();

        /* Drawing code ... */

    }
}

The problem I'm facing is that InvokeDraw() will not call the parent's Draw() method, but rather the extended class' own Draw() method, thus causing an infinite loop.

Although the issue is fairly logical, I am having a hard time figuring out a workaround on that. How to accomplish this task?

Desired effect

chart

Infinite loop problem

chart

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

On a superficial level, inheritance works like merging code. Inherited methods are part of the child class as if they were native to the class:

class A {

    public function foo() {
        echo 'foo';
    }

    public function bar() {
        echo 'bar';
    }

}

class B extends A { }

For all intents and purposes, this is equivalent to writing:

class B {

    public function foo() {
        echo 'foo';
    }

    public function bar() {
        echo 'bar';
    }

}

Class B has the function foo and bar as if they were part of its declaration.

Overriding methods in a child class replaces the one specific implementation with another:

class B extends A {

    public function bar() {
        echo 'baz';
    }

}

This is as if B was declared like this:

class B {

    public function foo() {
        echo 'foo';
    }

    public function bar() {
        echo 'baz';
    }

}

With one exception: the parent's implementation of a method is available using the parent keyword. It does not change the context in which the code is executed, is merely uses the parent's implementation of the method:

class B extends A {

    public function bar() {        public function bar() {
        parent::bar();      --->       echo 'bar';
    }                              }

}

It works in the same context of the current instance of B, it just pulls the old code of the parent out of the ether.

If you call another method in the parent's method, it executes in the context of the child, not in the context of the parent class. Because you have not instantiated the parent, you are working with a child. To demonstrate with properties (it works the same with methods):

class A {

    protected $value = 'bar';

    public function bar() {
        echo $this->value;
    }

}

class B extends A {

    protected $value = 'baz';

    public function bar() {
        parent::bar();     // outputs "baz"
        echo $this->value; // outputs "baz"
    }

}

As such, there is no solution to your problem. You cannot call a method in the "parent's context". You can call code of the parent in the current context, that's all. What you're creating is a simple loop, because it doesn't matter whether the code is inherited or not, it all works in the same context.

You need to redesign that class to not call methods in a loop.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...