1

子クラスに必要なメソッドを指定したい基本クラスがありますが、それら自体は実装しません。ただし、子クラスのメソッドは、基本クラスの定義とは異なる数のパラメーターを持つ場合があります。

抽象メソッドでこれを試してみましたが、php はこれを許可しません。出来ますか?

4

4 に答える 4

6

子クラスの関数は、エラーを発生させずに、追加のオプションの引数を署名に追加できます。

abstract class Foo {
  abstract function bar($a);
}

class NewFoo extends Foo {

  function bar($a, $b = null) {
    //do something
  }
}
于 2008-12-12T10:27:48.843 に答える
3

パラメーターなしで抽象メソッドを指定し、サブクラス化されたメソッドが func_get_args を介して引数にアクセスする必要があることを除けば、これがどのように可能になるかわかりません。

于 2008-12-12T04:42:43.143 に答える
1

これは、PHP のオブジェクト指向の弱点の 1 つであり、この種のユース ケースを処理するように設計されていないと言えます。オーバーロードされたメソッドを許可することを意図していませんでした

上記の両方の方法で、一種のハックとして話していることを実際に行うことができます。

func_get_args()

または、(言及したコメンターのように)引数の配列を渡すだけです。または、引数をデータ メンバーとして持つオブジェクトを渡すこともできます。次に、子メソッドのパラメーター/引数オブジェクトを拡張できます。

要点は、PHP は制限ではなく寛容さを重視する言語であるということです。抽象クラスには、PHP での非常に基本的な実装があります。このような多くの構造が必要な場合、PHP は最適な言語選択ではない可能性があります。

于 2008-12-12T06:37:15.860 に答える
0

かなり遅いので、これは本番環境で使用したいと思う答えではないと思いますが、それのために、Reflectionを使用して何かを書いてみました。これはうまくいくようです。サブクラスのメソッド宣言は明らかに一致するはずなので、引き続きE_STRICTを取得します。

class a {
    protected $requiredMethodsInSubclass = array( 'method1', 'method2', 'method3' );

    public function __construct() {
        $reflObject = new ReflectionObject($this);

        $className = $reflObject->getName();

        if ($className == __CLASS__) {
            //this class is being instanciated directly , so don't worry about any subclasses
            return;
        }

        foreach ($this->requiredMethodsInSubclass as $methodName) {
            try {
                $reflMethod = $reflObject->getMethod($methodName);
            } catch (ReflectionException $e) { //method not anywhere
                trigger_error("Method $methodName is not declared in class " . __CLASS__ . " or subclass $className", E_USER_ERROR);
                continue;
            }

            $declaringClass =  $reflMethod->getDeclaringClass();

            if ($declaringClass->getName() == __CLASS__) {
                //method is declared in this class, not subclass
               trigger_error("Method $methodName is not declared in subclass $className", E_USER_ERROR);
            }
        }
    }

    public function method1() {

    }

    public function method2($a) {

    }
 }



class b extends a {
    public function __construct() {
        parent::__construct();

        //some stuff
    }


    public function method2($a, $b, $c) {

    }

}



$b = new b();
于 2008-12-12T10:11:17.177 に答える