0

我有两个类,Foo扩展如下: BarBarFoo

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

有几个解决方案,最简单的方法是使用第二个变量作为扩展默认值,然后合并数组。

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. 这就是它所做的一切。

您的 print 方法输出$defaults此时将是(3,4)因为您将它们初始化为受保护的 var。

于 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 回答