访问父级';从父项';PHP中的上下文
我有一个名为ClassA的绘图PHP类,它被许多其他绘图类扩展,例如ClassB 我需要继承的类触发其父类的Draw()方法。但是,在我的特殊情况下,我不想直接调用这样的方法(例如:访问父级';从父项';PHP中的上下文,php,class,Php,Class,我有一个名为ClassA的绘图PHP类,它被许多其他绘图类扩展,例如ClassB 我需要继承的类触发其父类的Draw()方法。但是,在我的特殊情况下,我不想直接调用这样的方法(例如:parent::Draw())。我想要第三个函数(例如:parent::InvokeDraw())从父级上下文中调用我的绘图方法 下面是一些代码来说明: class ClassA { function Draw() { /* Drawing code ... */ }
parent::Draw()
)。我想要第三个函数(例如:parent::InvokeDraw()
)从父级上下文中调用我的绘图方法
下面是一些代码来说明:
class ClassA
{
function Draw()
{
/* Drawing code ... */
}
function InvokeDraw()
{
$this->Draw();
}
}
class ClassB extends ClassA
{
function Draw()
{
parent::InvokeDraw();
/* Drawing code ... */
}
}
我面临的问题是InvokeDraw()不会调用父类的Draw()方法,而是调用扩展类的ownDraw()方法,从而导致无限循环
虽然这个问题相当合乎逻辑,但我很难找到解决办法。如何完成这项任务
预期效果
无限循环问题
这是一种使用静态方法的方法
<?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();
编辑:
为了回答您下面的评论,我将添加一个关于您的代码如何工作以及此代码如何工作的简短描述
代码中发生了什么:
B
并开始使用它B
类和B
对象中工作时,我们调用B->Draw()
B->Draw()
静态调用(这意味着类方法)A::Invoke()
从类A调用,但是我们仍然使用B
对象A::Invoke()
调用$this->Draw()
目前我们正在处理B
对象,$this
引用了ClassB
的一个实例B
并开始使用它B
类和B
对象中工作时,我们调用B->Draw()
B->Draw()
静态调用(这意味着类方法)A::从类A调用
,但是以及在您的代码中,我们仍然在使用B
对象A::Invoke()
调用self::Draw()
,这与ClassA::Draw()
基本相同,因为它是一个静态方法,所以我们不关心当前使用的对象,我们调用A
的Draw()
方法A::Draw()
方法根据需要执行<?php
class ClassA
{
function Draw()
{
echo "DrawA";
/* Drawing code ... */
}
function InvokeDraw()
{
$this->Draw();
}
}
class ClassB extends ClassA
{
function Draw()
{
echo "DrawB";
$x = new parent;
$x->InvokeDraw();
/* Drawing code ... */
}
}
echo "Begin:<br>";
$cb = new ClassB();
$cb->Draw();
B
并开始使用它B
类和B
对象中工作时,我们调用B->Draw()
B->Draw()
创建A
的一个实例B->Draw()
调用A->Invoke()
,这意味着我们开始处理类A
的实例对象,而不是像以前那样的B
B
甚至是存在的,并且只使用A
A->Invoke()
调用$this->Draw()
,这意味着我们正在调用A->Draw()
,因为我们已经在处理类A
的实例A->Draw()
按预期执行A::Draw()
时可以使用它们。如果我们使用非静态方法,那么我们需要在方法的参数内传递所需的数据
我希望这能说明问题。上面的顺序没有正确的术语,但它是故意写的,我认为这样更容易理解流程。我非常喜欢你的问题,我做了一些研究,并尝试与我的第一个答案相同,但没有静态调用:
<?php
class ClassA
{
function Draw()
{
echo "DrawA";
/* Drawing code ... */
}
function InvokeDraw()
{
$this->Draw();
}
}
class ClassB extends ClassA
{
function Draw()
{
echo "DrawB";
$x = new parent;
$x->InvokeDraw();
/* Drawing code ... */
}
}
echo "Begin:<br>";
$cb = new ClassB();
$cb->Draw();
从表面上看,继承就像是合并代码。继承的方法是子类的一部分,就像它们是该类的本机方法一样:
class A {
public function foo() {
echo 'foo';
}
public function bar() {
echo 'bar';
}
}
class B extends A { }
就所有意图和目的而言,这相当于书写:
class B {
public function foo() {
echo 'foo';
}
public function bar() {
echo 'bar';
}
}
类B
具有函数foo
和bar
,就好像它们是其声明的一部分一样
子类中的重写方法将一个特定实现替换为另一个实现:
class B extends A {
public function bar() {
echo 'baz';
}
}
这就好像B
是这样声明的:
class B {
public function foo() {
echo 'foo';
}
public function bar() {
echo 'baz';
}
}
除了一个例外:父对象的方法实现可以使用parent
关键字来实现。它不会更改执行代码的上下文,只是使用父级的方法实现:
class B extends A {
public function bar() { public function bar() {
parent::bar(); ---> echo 'bar';
} }
}
它在当前B
实例的相同上下文中工作,它只是将父级的旧代码从以太网中拉出
如果在父类的方法中调用另一个方法,它将在子类的上下文中执行,而不是在父类的上下文中执行。因为您没有实例化父对象,所以您正在处理子对象。要使用属性进行演示(与方法的效果相同):
因此,你的问题没有解决办法。不能在“父上下文”中调用方法。您可以在当前上下文中调用父级的代码,仅此而已。您所创建的是一个简单的循环,因为不管代码是否被继承,它都在相同的上下文中工作
您需要重新设计该类,以避免在循环中调用方法。正如deceze所说,除非重新设计该类,否则您的问题没有解决方案 如果您使用的是PHP5.4,那么可以使用 创建2个特征,每个特征都有自己的
Draw
功能。然后在父母身上使用一个特征,在孩子身上使用另一个特征
然后,为了从子函数访问父函数,将InvokeDraw
别名设置为父函数Draw
class B extends A { public function bar() { public function bar() { parent::bar(); ---> echo 'bar'; } } }
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"
}
}
<?php
trait DrawingA
{
function Draw()
{
echo 'I am the parent';
}
}
trait DrawingB
{
function Draw()
{
echo 'I am the child';
}
}
class ClassA
{
use DrawingA;
}
class ClassB extends ClassA
{
use DrawingA, DrawingB {
DrawingB::Draw insteadof DrawingA;
DrawingA::Draw as InvokeDraw;
}
}
$b = new ClassB();
echo 'Child: ', $b->Draw(), PHP_EOL;
echo 'Parent: ', $b->InvokeDraw() . PHP_EOL;
/*
Outputs:
Child: I am the child
Parent: I am the parent
*/