3

基本クラスでメソッドを 1 回定義し、クラス階層内の連続するコンストラクターでそれを呼び出したいと考えています。呼び出されるたびに、呼び出し元のクラスのプロパティを操作したいと考えています。

たとえば、A は基本クラスで、メソッドはここで定義されています。B は A から継承し、C は B から継承します。

具象クラス C をインスタンス化すると、コンストラクターは基本クラス メソッドを呼び出し、C のプロパティで動作するようにします (これは、初期化時に入力するプライベート配列になります)。

次に、C のコンストラクターが を呼び出しますparent::__construct。B コンストラクターが基底クラスのメソッドを呼び出すとき、メソッドは B のプロパティを操作する必要があります。B コンストラクターが完了する前に を呼び出しparent::_construct、A コンストラクターが A のプロパティを操作します。

parent::__constructLSB を調べていましたが、転送呼び出しのため正しく動作しません。get_parent_class()in の代わりにの結果を使用しようとしましたparent::が、は定数ではないstatic::propertyNameため、エラーが発生しました。propertyName

これどうやってするの?

編集: コード例を次に示します。以下のコードは「PQPQP Q」を出力します。「PQRST U」を出力させたい。

class A {
    private $property = array('P','Q');

    function __construct() {
        $this->myMethod();
    }

    public function myMethod() {
        foreach ($this->property as $value) {
            echo $value . " ";
        }
    }
}

class B extends A {
    private $property = array('R','S');

    function __construct()
    {
        parent::__construct();
        $this->myMethod();
    }
}

class C extends B {
    private $property = array('T','U');

    function __construct()
    {
        parent::__construct();
        $this->myMethod();
    }
}

$c = new C();
4

4 に答える 4

1

私の知る限り、それは不可能です。private の場合、変数はメソッドで使用できず、public/protected の場合は上書きされます。

渡すことで、目的の結果を得ることができます

$this->property

このような各 myMethod 呼び出しで-

$this->myMethod($this->property)

それに応じて myMethod 定義を変更します。

于 2012-08-06T14:32:48.663 に答える
0

あなたの例は$propertyas として定義されてprivateおり、決してオーバーライドしないため、タイプormyMethodのオブジェクトがインスタンス化されると、 classのコンストラクターが実行され、クラスの値がisから呼び出されます。CBAmyMethod()A$propertyarray('P', 'Q');

「PQRST U」を出力したい場合はmyMethod()、個々のクラスの__construct()メソッドをオーバーライドして呼び出すか、子クラスがその値を上書きできるように宣言$propertyする必要があります。protected

このようなもの:

class A {
    private $property = array('P','Q');

    function __construct() {
        $this->myMethod();
    }

    public function myMethod() {
        foreach ($this->property as $value) {
            echo $value . " ";
        }
    }
}

class B extends A {
    private $property = array('R','S');

    function __construct()
    {
        parent::__construct();
        $this->myMethod();
    }

    public function myMethod() {
        foreach ($this->property as $value) {
            echo $value . " ";
        }
    }
}

class C extends B {
    private $property = array('T','U');

    function __construct()
    {
        parent::__construct();
        $this->myMethod();
    }

    public function myMethod() {
        foreach ($this->property as $value) {
            echo $value . " ";
        }
    }
}

$c = new C();

またはこれ:

class A {
    protected $property = array('P','Q');

    function __construct() {
        $this->myMethod();
    }

    public function myMethod() {
        foreach ($this->property as $value) {
            echo $value . " ";
        }
    }
}

class B extends A {
    protected $property = array('R','S');

    function __construct()
    {
        parent::__construct();
        $this->myMethod();
    }
}

class C extends B {
    protected $property = array('T','U');

    function __construct()
    {
        parent::__construct();
        $this->myMethod();
    }
}

$c = new C();
于 2012-08-06T14:37:59.093 に答える
0

proptery子クラスでオーバーロードできません。をC取得すると、プライベート プロパティはAもうありません。それらにアクセスする方法はありません(リフレクションの外)。これを行う唯一の方法は、プロパティをチェーンで渡すことですsomeMethodが、これには目的のプロパティへのアクセスが必要です。

子は親プロパティをオーバーライドするだけなので、使用しても機能しprotectedません。

これに対する解決策は、(is-a) である必要はありませC が、 (has-a .. 構成)Cのプロパティを持ちます。Aただし、これには階層の再作成が必要であり、呼び出しはより明示的にする必要があります。何かのようなもの

class C {
   private $b;
   private $properties = array('T', 'U');
   public function __construct(B $b) {
      $this->b = $b;
   }
   public function someMethod() {
      $this->b->someMethod($properties);
   }
}
class B {
   private $properties = array('R', 'S');
   private $a;
   public function __construct(A $a) {
      $this->a = $a;
   }
   public function someMethod($properties) {
      $this->a->someMethod(array_merge($this->properties, $properties));
   }
}
class A {
   private $properties = array('P', 'Q');
   public function someMethod($properties) {
      //your implementation plus an array_merge
   }
}

これは明らかに定義の冗長性を高めますが、これは悪いことです。あることを今のやり方でしなければならない理由を再考したくなるかもしれません。sを使用してこれを回避できる場合がありますtrait(PHP 5.4 を使用していると仮定します)。

于 2012-08-06T14:46:42.507 に答える
0

私があなたを正しければ、これはあなたの例です:

class A {
    public function __construct() {
    }

    public function someMethod($arg) {
        $someProperty = $arg;
    }
}

class B extends A {
    public function __construct() {
        parent::__construct();
    }
}

class C extends B {

    private $someProperty;

    public function __construct() {
        parent::__construct();
    }
}

すべてが期待どおりに機能します。問題は 1 つだけです。クラス A にはプロパティがありませんsomeProperty。クラス A で使用する場合は、そこで定義する必要があります。サブクラスで使用する場合は、作成する必要がありますprotected。したがって、クラス A は次のようになります。

class A {

    protected $someProperty;

    public function __construct() {
    }

    public function someMethod($arg) {
        $this->someProperty = $arg;
    }
}

これで、クラス B と C で使用でき、クラス A でプロパティを使用できるようになりましたsomeMethod

$instance = new C();
$instance->someMethod("test");
于 2012-08-02T06:38:48.553 に答える