PHP 5.2.0 で仕様が変わっていたインターフェイス

| | コメント(4)

5.2.0 で仕様が変わっていたインターフェイス

5.2.0 でインターフェイスに対して手が加えられたよう。だけど、この仕様変更についてはどうかと疑問を感じました。

自分はインターフェイスについてこう考えている

疑問点を述べる前に、自分が持つインターフェイスについての考え方を述べておきます。インターフェイスとは、オブジェクトに対して所属するクラスに関係なく公開された振る舞いを定義する方法だと考えています。例えば…


// 感情表現するためのインターフェイスを定義

/**
 * ツンツンするメソッドを定義します。
 */
interface ITuntun
{
    public function tun();
}

/**
 * デレデレするメソッドを定義します。
 */
interface IDeredere
{
    public function dere();
}


/**
 * モチモチするメソッドを定義します。
 *
 */
interface IMochimochi
{
    public function mochi();
}
// 感情表現できるクラスを定義

/**
 * お嬢様を表します。
 */
class Ojyohsama implements ITuntun, IDeredere
{
    /**
     * ツンツンします。
     */
    public function tun()
    {
        echo 'べ、べつにあんたのためじゃないんだからね!';
    }
    
    /**
     * デレデレします。
     */
    public function dere()
    {
        echo '頼れるのはあんただけなんだから…';
    }
}


/**
 * ひこにゃんを表します。
 */
class Hikonyan implements IDeredere, IMochimochi
{
    /**
     * デレデレします。
     */
    public function dere()
    {
        echo '一緒に写真とるにゃんー1枚50元払えニャン';
    }
    
    /**
     * モチモチします。
     */
    public function mochi()
    {
        echo 'エレベータにはさまったニャン!';
    }
    
}


// んでもって実行。

// お嬢様もひこにゃんも組み込みクラスも一緒くたにして…
$objects = array(
        new Ojyohsama(),
        new Hikonyan(),
        new stdclass(),
        new DOMDocument(),
    );

// オブジェクトのうち、IDeredere を実装したものだけデレデレさせる。
foreach ($objects as $object)
{
    if ($object instanceof IDeredere)
    {
        $object->dere();
    }
}


インスタンスの初期化をインターフェイスで縛ることに意味があるのか?

付録 B. PHP 5.1.x から PHP 5.2.x への移行その他の機能向上 より。

インターフェイスのコンストラクタで、 実装クラスのコンストラクタのシグネチャを強制できるようになりました。

PHP 5.2.0 以降で、インターフェイスにコンストラクタを定義できるようになりました。 しかし、インターフェイスでコンストラクタを宣言した場合は、 そのインターフェイスを実装するクラスは インターフェイスのコンストラクタと同じシグネチャのコンストラクタを持つ必要があります。 ここでいう「シグネチャ」とは、パラメータや返り値の定義のことです。 また、型ヒントや 参照渡し/値渡し の区別なども含まれます。

コンストラクタがはたしてインターフェイスに含まれるべきかを焦点にすると、含まれるべきではないと思います。コンストラクタはあくまでクラスのインスタンスを初期化する役割であり、またその手段のシンタックス シュガーであり、オブジェクトの振る舞いの定義とは違います。振る舞いを示すメソッドと表現が似ているだけで別物と考えるべきです。

また、インターフェイスは横断的に implements できるので、当然コンストラクタの衝突が考えられます。多重継承の問題が再蜂起しそう…。

そもそもの要求であるコンストラクタのシグネチャを保証させたいのなら、抽象クラスを使うべきだし、オブジェクトの作成方法を統一するならデザパタの Factory Method パターンがより分かりやすく思えます。

インターフェイスはインスタンスに関わる定義だけじゃない?

付録 B. PHP 5.1.x から PHP 5.2.x への移行その他の機能向上 より。

abstract static なクラス関数が削除されました。

ちょっとした手違いで、PHP 5.0.x および 5.1.x では abstract static な関数をクラス内で定義できてしまっていました。PHP 5.2.x では、 これはインターフェイス内でのみ定義できるようになりました。

static なメンバの定義について、これもインターフェイスがオブジェクトの振る舞いを定義するものならお役違いだと思います。static なメンバには当然オブジェクトがないのでインターフェイスを利用する場面でもありません。

[ここにオブジェクトのクラスに存在する static メソッドを呼び出すコードを書く]

無理して使うほどでもないし、abstract static の存在からして謎。実装を再定義する必要があるものを static にする設計がおかしい気がします。

追記

こうして考えると PHP のインターフェイスはテンプレートとしての役割なのかなぁ…。もう少し考えてみます。

コメント(4)

I thought that was extremeley exciting. Many thanks for your unusual details. I'll maintain using this.

You've got your point via a great deal far better than I at any time could, thank you!

Incredibly cool! I assistance your view!

static なメンバの定義について、これもインターフェイスがオブジェクトの振る舞いを定義するものならお役違いだと思います。static なメンバには当然オブジェクトがないのでインターフェイスを利用する場面でもありません。

[ここにオブジェクトのクラスに存在する static メソッドを呼び出すコードを書く]

無理して使うほどでもないし、abstract static の存在からして謎。実装を再定義する必要があるものを static にする設計がおかしい気がしま

コメントする


画像の中に見える文字を入力してください。

このブログ記事について

このページは、zenithが2007年7月 4日 13:40に書いたブログ記事です。

ひとつ前のブログ記事は「要らないコメントを削除する」です。

次のブログ記事は「Unicode のカテゴリを利用する」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Powered by Movable Type 4.12