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

查看:125
本文介绍了在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()方法,

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 c $ c>方法并使它使用 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() b $ b
  3. B-> Draw()静态调用(意味着类方法) A :: Invoke $ c>从A类 BUT ,我们仍然使用 B 对象。

  4. 静态调用 A :: Invoke()调用 $ this-> Draw(); c> 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-> Draw() B 类中工作 B object。

  3. B-> Draw() A :: Invoke 从类A BUT 以及在代码中我们仍然使用 B 对象。 li>
  4. 静态调用 A :: Invoke()调用 self :: Draw()它基本上与 ClassA :: Draw()相同,因为它是一个静态方法,我们不关心我们目前使用的对象,我们称之为 A 的 Draw()方法。

  5. :: 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-& / code> class AND B 对象。

  3. B-& code> CREATES 的实例 A

  4. B- > Draw()调用 A-> Invoke()这意味着我们开始处理一个对象, $ c> 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(),因为我们已经使用了一个实例 c

  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天全站免登陆