在PHP中从父级上下文访问父级的重写方法 [英] Access parent's overridden method from parent's context in PHP

查看:115
本文介绍了在PHP中从父级上下文访问父级的重写方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为 ClassA 的图形PHP类,该类被许多其他图形类(例如 ClassB )扩展了.

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

我需要继承的类来触发其父类的 Draw()方法.但是,在我的特定情况下,我不想直接调用这种方法(例如:parent::Draw()).我想要第三个函数(例如parent::InvokeDraw())从父级上下文中调用我的绘图方法.

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 ... */

    }
}

我面临的问题是 InvokeDraw()不会调用父级的 Draw()方法,而是扩展类自己的 Draw( )方法,从而导致无限循环.

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?

推荐答案

这是使用静态方法的

<?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:<br>";

$cb = new ClassB();
$cb->Draw();

请注意,我唯一更改的是InvokeDraw()方法,并使其使用self来引用类,而不是像$this

Note that the only thing I changed is the InvokeDraw() method and made it use self which refers to a class, rather than object as it is with $this

输出:

Begin:
DrawBDrawA

修改: 为了在下面回答您的评论,我将简短描述您的代码如何工作以及该代码如何工作.

To answer your comment below I will add a short description of how your code works and how this code works.

代码中会发生什么:

  1. 我们创建B并开始使用它
  2. B类和B对象中工作时,我们调用B->Draw().
  3. B->Draw()从类A 但是静态调用(这表示类方法)A::Invoke(),我们仍在使用B对象.
  4. 静态调用A::Invoke()调用$this->Draw();,并且由于我们当前正在使用B对象,因此$this引用ClassB的实例.
  5. 然后我们开始循环播放.
  1. We create B and start working with it
  2. We call B->Draw() while working within B class AND B object.
  3. B->Draw() calls statically(that means class method) A::Invoke() from class A BUT we are still using B object.
  4. Static call A::Invoke() calls $this->Draw(); and as we are working currently with B object, $this refers to an instance of ClassB.
  5. And here we go looping.

上面的代码会发生什么:

What happens in the code above:

  1. 我们创建B并开始使用它
  2. B类和B对象中工作时,我们调用B->Draw().
  3. B->Draw()从类A 中静态调用(这意味着类方法)A::Invoke,以及在您的代码中,我们仍在使用B对象.
  4. 静态调用A::Invoke()调用self::Draw(),它与ClassA::Draw()基本上相同,并且由于它是静态方法,因此我们不在乎当前正在使用的对象,因此我们将ADraw()方法.
  5. A::Draw()方法根据需要执行.
  1. We create B and start working with it
  2. We call B->Draw() while working within B class AND B object.
  3. B->Draw() calls statically(that means class method) A::Invoke from class A BUT as well as in your code we are still using B object.
  4. Static call A::Invoke() calls self::Draw() which is basically the same as ClassA::Draw() and because it's a static method, we don't care what object we are currently working with and we call the A's Draw() method.
  5. A::Draw() method executes as we need.

我将在第二个答案中为代码提供相同的解释,该答案不使用静态调用:

I will provide the same explanation for the code in my second answer, which doesn't use static calls:

  1. 我们创建B并开始使用它
  2. B类和B对象中工作时,我们调用B->Draw().
  3. B->Draw() 创建 A的实例.
  4. B->Draw()调用A->Invoke(),这意味着我们开始使用作为类A而不是B实例的对象.
  1. We create B and start working with it
  2. We call B->Draw() while working within B class AND B object.
  3. B->Draw() CREATES an instance of A.
  4. B->Draw() calls A->Invoke() which means we start to work with an object that is instance of class A and not B like before.

在这一点上,我们完全忘记了B甚至存在并且仅与A

At this point we completely forget that B even exists and work only with A

  1. A->Invoke()调用$this->Draw(),这意味着我们正在调用A->Draw(),因为我们已经在使用类A的实例.
  2. A->Draw()执行符合我们的预期.
  1. A->Invoke() calls $this->Draw() which means that we are calling A->Draw(), because we already work with an instance of class A.
  2. A->Draw() executes as we expect.

从可用性的角度来看,我们可以看到静态方法更好,因为我们可以定义一些静态属性,并且可以在执行A::Draw()时使用它们.如果使用非静态方法,则需要在方法的参数内传递所需的数据.

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 A::Draw() executes. If we use non-static method, then we need to pass the data we need within arguments of our methods.

我希望这一点可以弄清楚.上面的序列没有正确的术语,但是它是有意编写的,我认为这样更容易理解流程.

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.

这篇关于在PHP中从父级上下文访问父级的重写方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆