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 メソッドのみをオーバーライドしたいので、ヘッダーとフッターは自動的に表示されますが、.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 には「Late Static Binding」がないため、呼び出されないという問題が発生する可能性がありますFooPage::displayContent。PHP 5.2 を実行している場合は、何もする必要はありません (ただし、debug_backtrace() を使用したいくつかのハックを除きます。正直なところ、この状況ではお勧めしません)。

さて、私の注意を喚起するのは、メソッドがすべて静的であるということです。これには理由がありますか?なぜインスタンスメソッドではないのですか? 私は次のようなものを期待します:

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 を使用しない方がよいでしょう。代わりに、文字列を作成し、最後のステップとして 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() メッセージを理解するオブジェクト (つまり、ポリモーフィック) である限り、問題はありません。

HTH

于 2012-11-01T12:03:41.000 に答える