0

私は2つのクラスを持ってFooおり、Barそれは以下のようにBar拡張Fooされています:

class Foo {
    protected 
        $options = array(), 
        $defaults = array(1, 2);

    public function __construct($options){
        array_push($this->options, $this->defaults);
    }
}

class Bar extends Foo {
    protected $defaults = array(3, 4);

    public function print(){
        print_r($this->$options);
    }
}

$bar = new Bar();
$bar->print();

私は結果がそうあるべきだと思っていましたが、そうarray(1,2,3,4)ですarray(3,4)
それを解決する方法は?

編集
私はスーパークラスの実装者であり、子クラスで実際に何が起こるかわからないため、Bar クラスにコンストラクターを持たせたくありません。

4

5 に答える 5

2

いくつかの解決策があります。最も簡単なのは、2 番目の変数を拡張デフォルトとして使用し、配列をマージすることです。

class Foo {
    protected
        $options = array(),
        $original_defaults = array(1, 2),
        $extended_defaults = array();

    public function __construct($options){
        array_merge($this->extended_defaults, $this->original_defaults);
        array_push($this->options, $this->original_defaults);
    }
}

class Bar extends Foo {
    protected $extended_defaults = array(3, 4);

    public function print(){
        print_r($this->$options);
    }
}

$bar = new Bar();
$bar->print();
于 2012-06-12T16:08:38.160 に答える
2

なぜあなたの配列を組み合わせるのですか?

に設定$defaultsしてから(1,2)(3,4)それらを連結している場所はどこにもありません。

コンストラクターは に追加(1,2)$optionsます。それだけです。

$defaultsこの時点での印刷メソッドの出力(3,4)は、保護された変数として初期化するためです。

于 2012-06-12T16:09:32.467 に答える
1

これらの値をオーバーライドしたくない場合は、private代わりにprotected. これにより、サブクラスがこれらの値をオーバーライドするのを防ぎます。

于 2012-06-12T16:04:07.397 に答える
1

まず、 という名前のメソッドを持つことはできませんprintprintは言語構造であり、オーバーライドできません。

次に、クラスのデフォルト値をプライベートにして、子クラスでオーバーライドする必要があります。次に、コンストラクターを呼び出すときに、それらを親で組み合わせることができます。何を達成しようとしているのかは 100% 明確ではありませんが、以下はサブクラスのデフォルト オプションをスーパークラスとマージします。

コンストラクタを削除するように更新

abstract class Foo {
    protected $options = array();

    private $defaults = array(1, 2);

   // Implementations of this class MUST define this method
   abstract function overrideDefaults(); 

    public function __construct($options = array()){
        // Merge any incoming options with the default options
        $this->options = array_merge($this->defaults, $options);

    }

    // Concrete children can use this method to modify the current options by 
    // passing in their own defaults.
    protected function modifyDefaults( $defaults ) {
        $this->options= array_merge( $this->defaults, $defaults );
    }

    public function printOps(){
        print_r($this->options);
    }
}

class Bar extends Foo {
    private $defaults = array(3, 4);

    public function overrideDefaults() {
        parent::modifyDefaults( $this->defaults );
    }
}

$bar = new Bar();
$bar->overrideDefaults();
$bar->printOps();

nowprintOpsメソッドもスーパークラスに移動したことに注意してください。出力:

Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 ) 
于 2012-06-12T16:19:51.993 に答える
0

「各子クラスにデフォルト値を持たせたいだけです」.

クラスごとに特定のデータが必要です。

「静的フィールド」を使用して、クラスを変数として機能させることができます。「静的メンバー」はあまり好きではありませんが、「ユースケース」には当てはまると思います。

class Foo {
    private 
      // (1) "private" only accessed by the class itself,
      // neither external code, or subclasses,
      // (2) "static", specific to the class,
      static $defaults = array(1, 2);

    protected 
      // want to be accessed only by class & subclasses
      $options = array();

    // when using "static fields" in constructor,
    // you need to override constructor
    public function __construct($options){
        array_push($this->options, Foo::$defaults);
    }

    // ops, "print" is reserved identifier
    // public function print(){

    public function display_options() {
        print_r($this->$options);
    }

    public function display_defaultoptions() {
      // in order to acccess "static fields",
      // you use the class id, followed by double colon,
      // not "$this->*"
      print_r(Foo::$defaults);
    }
} // class Foo

class Bar extends Foo {
private 
    // (1) "private" only accessed by the class itself,
    // neither external code, or subclasses,
    // (2) "static", specific to the class,
    static $defaults = array(1, 2);

    // when using "static fields" in constructor,
    // you need to override constructor
    public function __construct($options){
        array_push($this->options, Bar::$defaults);
    }

    public function display_defaultoptions() {
      // in order to acccess "static fields",
      // you use the class id, followed by double colon
      // not "$this->*"
      print_r(Bar::$defaults);
    }
} // class Bar

$bar = new Bar();
$bar->print();

乾杯

于 2012-06-12T17:46:03.483 に答える