通过继承初始化数组的最佳方法



我想通过继承定义初始化一个数组,具有以下约束:

  1. 无构造函数
  2. 开发人员使用基类的简单用法,定义如下

编辑:为了更好的易用性,给出了字符串数组作为示例,数组将加载"真实"世界中的对象

一种方法可以是合并每个子类initArray函数中的父数组,因此对于每个子类:

public function initArray() {
    return array_merge (
        parent::initArray(),
        array ("C1")
    );
}

但我想避免它(约束 2(

有什么想法吗?其他可能的实现?现有模式?谢谢

Class BaseClass {
    protected $myArray;
    public function initArray() {
        return array ();
    }
    public function init(){
        $this->myArray=$this->initArray();
    }
    public function getMyArray() {
        return $this->myArray;
    }
}
Class B extends BaseClass {
    public function initArray() {
        return array ("B1", "B2", "B3");
    }
}
Class C extends B {
    public function initArray() {
        return array ("C1");
    }
}
$c=new C();
$c->init();
print_r($c->getMyArray()); // return C1 and I would like C1, B1, B2, B3

如果你想返回数组,你可以像这样 eval.in 代码

<?php
Class BaseClass {
    protected $myArray;
    public function initArray() {
        return array ();
    }
    public function init(){
        $this->myArray=$this->initArray();
    }
    public function getMyArray() {
        return $this->myArray;
    }
}
Class B extends BaseClass {
    public function initArray() {
        $parentArray = parent::initArray();
        $parentArray[]="B1";
        $parentArray[]="B2";
        $parentArray[]="B3";
        return $parentArray;
    }
}
Class C extends B {
    public function initArray() {
        $parentArray = parent::initArray();
        $parentArray[]="C1";
        return $parentArray;
    }
}
$c=new C();
$c->init();
print_r($c->getMyArray()); // return C1 and I would like C1, B1, B2, B3

此代码正常工作(假设 BaseClass 没有构造函数(。它回答了这个问题,但我觉得很沉重!!

Class BaseClass {
    protected $myArray;
    public function initArray() {
        return array ();
    }
    public function getMyArray() {
        if ($this->myArray===null) $this->_initArray();
        return $this->myArray;
    }
    private function _initArray() {
        $ancestors=$this->_getAncestors(static::Class);
        $this->myArray=array();
        foreach ($ancestors as $ancestor) {
            /** @var BaseClass $ancestorInstance */
            $ancestorInstance = new $ancestor();
            $this->myArray=array_merge($this->myArray, $ancestorInstance->initArray());
        }
    }
    private function _getAncestors ($class) {
        for ($classes[] = $class; $class = get_parent_class ($class); $classes[] = $class);
        return $classes;
    }
}
Class B extends BaseClass {
    public function initArray() {
        return array ("B1", "B2", "B3");
    }
}
Class C extends B {
    public function initArray() {
        return array ("C1");
    }
}
$c=new C();
$myArray=$c->getMyArray();
print_r($myArray); // returns now C1, B1, B2, B3

一个答案可以是以下(包括继承方法漏洞(。我的上帝!如果有人有更好的解决方案....

Class BaseClass {
    protected $myArray;
    public function initArray() {
        return array ();
    }
    public function getMyArray() {
        if ($this->myArray===null) $this->_initArray();
        return $this->myArray;
    }
    private function _initArray() {
        $ancestors=$this->_getAncestors(static::Class);
        $this->myArray=array();
        foreach ($ancestors as $ancestor) {
            /** @var BaseClass $ancestorInstance */
            $ancestorInstance = new $ancestor();
            if ($this->_checkIfMethodIsPresent($ancestor, 'initArray')) {
                $this->myArray = array_merge($this->myArray, $ancestorInstance->initArray());
            }
        }
    }
    private function _getAncestors ($class) {
        for ($classes[] = $class; $class = get_parent_class ($class); $classes[] = $class);
        return $classes;
    }
    private function _checkIfMethodIsPresent($className, $methodName) {
        $reflector = new ReflectionClass($className);
        $found=false;
        foreach ($reflector->getMethods() as $method) {
            if ($method->class == $className && $methodName==$method->name) {
                $found=true;
                break;
            }
        }
        return $found;
    }
}
Class B extends BaseClass {
    public function initArray() {
        return array ("B1", "B2", "B3");
    }
}
Class C extends B {
    // No initArray method
}
Class D extends C {
    public function initArray() {
        return array ("D1");
    }
}
$d=new D();
$myArray=$d->getMyArray();
print_r($myArray); // returns now D1, B1, B2, B3

推入数组,不要返回:

Class BaseClass {
    protected $myArray;
    public function init(){
        $this->myArray=[];
    }
    public function getMyArray() {
        return $this->myArray;
    }
}
Class B extends BaseClass {
    public function initArray() {
        array_push($this->myArray, "B1", "B2", "B3");
    }
}
Class C extends B {
    public function initArray() {
        $this->init();
        parent::initArray();
        array_push($this->myArray, "C1");
    }
}
$c=new C();
$c->initArray();
print_r($c->getMyArray()); // return C1 and I would like C1, B1, B2, B3

PS:这个问题缺乏很好的老多态性,但它只是一个快速的解决方案,你应该改进这个算法。

嘿,试试看!

    <?php
Class BaseClass {
    protected $myArray = array();
    public function __construct($content = false) {
        if ($content){
            array_push($this->myArray, explode(',', $content));
        }
    }
    public function getMyArray() {
        return $this->myArray[0];
    }
}
Class B extends BaseClass {
    public function __construct($content) {
        parent::__construct("$content,B1,B2,B3");
    }
}
Class C extends B {
    public function  __construct() {
        parent::__construct('C1');
    }
}
$c=new C();
print_r($c->getMyArray()); // return C1 and I would like C1, B1, B2, B3

改进了接受对象的示例:

<?php
Class BaseClass {
    protected $myArray = array();
    public function __construct($content = false, $content2 = false) {
        if ($content){
            if (is_array($content)){
                array_push($this->myArray, $content);
            } else if (is_object($content)) {
                if ($content2) {
                    $convContent = array_merge((array) $content2, (array) $content);
                } else {
                    $convContent = get_object_vars($content);
                }
                array_push($this->myArray, $convContent);
            } else {
                array_push($this->myArray, explode(',', $content));
            }
        }
    }
    public function getMyArray() {
        return $this->myArray[0];
    }
}
Class B extends BaseClass {
    private $cont1 = 'B1';
    private $cont2 = 'B2';
    private $cont3 = 'B3';
    public function __construct($content = false) {
        parent::__construct($this, $content);
    }
}
Class C extends B {
    private $cont1 = 'C1';
    public function  __construct($content = false) {
        parent::__construct($this, $content);
    }
}
$c=new C();
print_r($c->getMyArray()); // return C1 and I would like C1, B1, B2, B3

相关内容

最新更新