1

PHP に次のような親クラスがあるとします。

class A {

    private $property;

    public static function factory($arg) {
        $object = new A();
        $object->property = $arg;
        return $object;
    }

}

そして、私はそれを次のように拡張したいと思います:

class B extends A {

    public static function factory() {
        return parent::factory('constant');
    }

}

するとB::factory()、 type のオブジェクトが得られますA。タイプのオブジェクトが必要な場合はどうすればよいBですか? class のコードは何も変更できませんA

4

2 に答える 2

1

最初のバージョン

Aこれは、ファクトリ メソッドでクラスをハードコーディングしたためです。
classでは、tryAの代わりに$object = new A()(Php 5.3 が必要):

$class_name = get_called_class();
$object = new $class_name;

get_called_class()「静的メソッドが呼び出されるクラスの名前を取得します。」

短いバージョン:

$object = new static();

2 番目のバージョン (ハードコードされた親クラス):

オブジェクト プロパティを手動でコピーします。

$parent = parent::factory($args);
$obj = new static();
$obj->setTimestamp($parent->getTimestamp());
$obj->setTimezone($parent->getTimezone());
return $obj;

または、ハックを使用して自動的に実行します。

PHP でオブジェクトをキャストする方法

于 2012-05-16T11:07:21.247 に答える
0

あなたの例では:

  1. あなたには2つのクラスがあります(少なくとも)
  2. 両方のクラスをインスタンス化できます(純粋または抽象ではなく、具体的)
  3. あるクラスは別のクラスのスーパークラスです
  4. 両方のクラスは「ファクトリ」メソッドでインスタンス化されます
  5. サブクラスの「factory」メソッドは、スーパークラスの「factory」メソッドを呼び出すことができます
  6. 各「ファクトリ」メソッドは、いくつかのタイプまたはカウントのパラメーターを持つことができます

問題

さて、これが私の注意を引いたものです:

class B extends A {

    public static function factory() {
        return parent::factory('constant');
    }

}

短くて速い答え:

これを次のように変更します。

class B extends A {

    public static function factory() {
        return A::factory('constant');
    }

}

長く退屈なヒップスターの拡張回答:

静的関数をオーバーライド(および異なるパラメーターでオーバーロード)しようとしています。

静的メソッドが仮想であり、オーバーライドできると想定するというよくある間違いです。一部のプログラミング言語では許可されていますが(Object Pascal、Delphi)、許可されていない言語(C#、Java)もありますが、PHPはバージョンによって異なります。

正直なところ、「静的関数」は、メソッドではなく、クラスのすべてのメンバーにパブリックアクセスできる名前空間を持つグローバル関数のように機能します。常にグローバル関数として見ることをお勧めします。

乾杯。

于 2012-05-16T17:51:55.927 に答える