6

我有一个如下所示的抽象页面类:

abstract class Page {
    public static function display() {
        self::displayHeader();
        self::displayContent();
        self::displayFooter();
    }

    public static function displayContent() {
        print "<p>some content</p>";
    }

    public static function displayHeader() {
        include_once(kContent . "HeaderContent.class.php");
        HeaderContent::display();
    }

    public static function displayFooter() {
        include_once(kContent . "FooterContent.class.php");
        FooterContent::display();
    }
};

我想从中继承子类,并且只覆盖 displayContent 方法,因此页眉和页脚会自动显示,但仍然可以选择覆盖 display 方法,例如 .js 文件。

现在我有另一个类,看起来像这样:

class FooPage extends Page {
    public static function displayContent() {
        print "<p>Foo page</p>";    
};

现在,它不再调用 FooPage 的displayContent方法,而是调用超类中的方法。

为什么?我能做些什么?

编辑

我正在运行 PHP 5.2.17

4

1 回答 1

8

Ilija,PHP < 5.3 没有“后期静态绑定”,这就是为什么您可能会遇到FooPage::displayContent不被调用的情况。如果您运行的是 PHP 5.2,那么就没有什么可做的了(除了一些使用 debug_backtrace() 的 hack,老实说我不推荐这种情况)。

现在,真正引起我注意的是您的方法都是静态的;是否有一个原因?为什么它们不是实例方法?我希望是这样的:

include_once(kContent . "HeaderContent.class.php");
include_once(kContent . "HeaderContent.class.php");

abstract class Page 
{
    protected $header;
    protected $footer;

    public function __construct()
    {
        $this->header = new HeaderContent();
        $this->footer = new FooterContent();
    }

    public function display() 
    {
        $this->displayHeader();
        $this->displayContent();
        $this->displayFooter();
    }

    public function displayContent() 
    {
        print "<p>some content</p>";
    }

    public function displayHeader() 
    {
        $this->header->display();
    }

    public function displayFooter() 
    {
        $this->footer->display();
    }
};

class FooPage extends Page 
{
    public function displayContent() 
    {
        print "<p>Foo page</p>";
    }
}

稍后在您看来,您将编写如下内容:

$page = new FooPage();
$page->display();

需要考虑的一些事项:

  • 在生成视图内容时,通常最好不要使用 print/echo。而是尝试创建字符串并将打印/回显作为最后一步。这使得以后编写测试更容易。

例子:

public function display() 
{
    return 
           $this->displayHeader() . 
           $this->displayContent() . 
           $this->displayFooter();
}

public function displayContent() 
{
    return "<p>some content</p>";
}

public function displayHeader() 
{
    return $this->header->display();
}
....
$page = new FooPage();
echo $page->display();
  • 如果随着应用程序的增长需要这样做,可以将页眉和页脚作为 Page 构造函数参数传递。只要它们是理解 display() 消息(即多态)的对象,事情就应该没问题。

高温高压

于 2012-11-01T12:03:41.000 回答