我想通过继承定义初始化一个数组,具有以下约束:
- 无构造函数
- 开发人员使用基类的简单用法,定义如下
编辑:为了更好的易用性,给出了字符串数组作为示例,数组将加载"真实"世界中的对象
一种方法可以是合并每个子类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