【问题标题】:PHP OO: Calling methods on abstract classes?PHP OO:在抽象类上调用方法?
【发布时间】:2011-08-14 22:53:11
【问题描述】:

请有人帮忙解决以下问题?

我们有以下课程:

  • 抽象类元素{}
  • 抽象类容器扩展 元素{}
  • 抽象类字段扩展 容器{}

“元素”基类具有以下属性和方法:

//Element class
private $errors = array();

public function __construct()
{
}

public function setError($error)
{
$this->errors[] = $error;
}

public function getErrors()
{
return "<li>".implode("</li>\n",$this->errors);
}

“容器”只是对元素(对象)进行分组。

'Field' 类调用基类的 'setError' 方法并传递如下值:

//Field class
$this->setError("foo");

由于某种原因,基类中的 'errors' 属性没有获得添加到它的值,我猜这与对象的实例化方式有关,因为显然抽象类默认情况下没有实例化。

该字段的唯一实例是它的继承形式,即:

Text extends Field{}
$field = new Text(etc, etc)

你会如何解决这个问题?

【问题讨论】:

  • 能否展示元素和字段类的完整代码
  • 对于下一个投票否决的人来说,这个问题怎么不清楚?
  • “优先于类继承的对象组合。” (c) GoF

标签: php oop


【解决方案1】:

您必须在 Element 类中将 $errors 成员变量设置为 protected

//Element class
protected $errors = array();

现在,当您在 Text 类实例上调用继承的 setError() 函数时,Text 类实例没有自己的 $errors 数组,因此 PHP 为您提供了在Text 类的实例。然而,这是一个不同于 Elements 基类中的 $errors 成员变量。

将 $errors 成员变量设置为 'protected' 允​​许 Text 类的实例与 Element 基类中的变量进行交互,因此 PHP 不会为您创建新的 $error 成员(仅属于 Text 类)在运行中。

【讨论】:

  • 感谢 DWight,答案很好,但没有奏效。是不是因为在“Field”类中调用了“setError”方法,但实际上它的“Text”类被实例化了。我知道“文本”正在继承“字段”,但我想我会问吗?
  • 您没有在任何继承类中重新声明 $errors?
  • 另外,Field 类中的哪个方法包含对 $this->setError("foo") 的调用?您是否在 Text 类上调用相同的(继承的)方法? IE。 $text->theMethod()(theMethod 继承自 Field)。
  • 仅供参考,最好有所有相关类的代码。
  • 不,不在任何地方重新声明 $errors。在“字段”类中有一个名为“验证”的方法,这是一个抽象方法,几乎​​可以用于所有继承类。 'Text' 类只有一个 'getfield' 方法。对不起。
【解决方案2】:

为我工作:http://codepad.viper-7.com/Ool7zn

<?php

abstract class Element
{
    protected $errors = array();

    public function setError($error)
    {
        $this->errors[] = $error;
    }

    public function getErrors()
    {
        return "<li>".implode("</li>\n",$this->errors);
    }
}
abstract class Container extends Element{}
abstract class Field extends Container{}
class Text extends Field{}

$t = new Text;
$t->setError('foobar');

echo $t->getErrors();

?>

【讨论】:

  • 感谢 Teresko,但 'setError' 方法不是这样调用的。
  • 请注意,您没有显示它是如何被调用的 + 它实际上并不重要。
  • 我确实展示了它是如何调用的。它在“字段”类中被调用,当然它的调用方式很重要。你不能凭空称呼它,但无论如何谢谢。
  • 显然还有其他事情发生,但 Tereskos 的例子很好,因为它表明这应该可以工作,所以要把它作为回答。
  • 您能否将代码粘贴到您的答案中,以免我们丢失解决方案。
猜你喜欢
  • 1970-01-01
  • 2012-09-21
  • 2011-08-14
  • 1970-01-01
  • 1970-01-01
  • 2017-05-02
  • 2023-03-03
  • 2021-10-13
  • 2016-06-20
相关资源
最近更新 更多