Использование наследования в PHP для добавления данных в массив из нескольких подклассов - PullRequest
2 голосов
/ 03 февраля 2012

Отказ от ответственности: Это не домашняя работа. Кроме того, я описываю упрощенную ситуацию, так что соблюдайте мой полупсудо-код.

Мне кажется, что это довольно стандартная ООП-ситуация, но я не уверен, что это лучший способ справиться с этим. Допустим, у меня есть 3 класса: Base, A и B. Класс A расширяется Base и B расширяется A. Конструктор класса Base выполняет запрос к базе данных, который извлекает различные метаданные, определенные в массиве. Смотрите ниже:

Class Base {

    public $meta_data = array('col1','col2');

    function __construct() {
        $db->query("select ".join(',',$this->meta_data)." from table");
    }

}

Class A extends Base {

    public $meta_data = array('col3','col4');

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

}

Class B extends A {

    public $meta_data = array('col5','col6');

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

}

Когда я создаю объект new B(), я хочу, чтобы sql-запрос базового конструктора выглядел так:

select col1, col2, col3, col4, col5, col6 from table;

И когда я создаю объект new Base(), я хочу, чтобы SQL-запрос выглядел так:

select col1, col2 from table;

Теперь ... Я технически знаю, как это сделать (возможно, грубо), но мне любопытно, каков правильный путь без слишком большой репликации кода и с учетом гибкости в будущем (то есть, добавляя подкласс из б). Мне нужно объединить массивы $meta_data на каждом уровне наследования вплоть до конструктора в классе Base.

Есть идеи?

Ответы [ 3 ]

3 голосов
/ 03 февраля 2012

Когда вы расширяете класс и определяете новое свойство, вы переопределяете значения, установленные в родительском классе. Я хотел бы удалить массив $meta_data из всех, кроме Base. Затем в ваших расширяющих классах создайте функцию, похожую на:

После того, как я решил ее очень просто, я решил, что в Base мне нужно что-то вроде следующего:

protected function addToMetaData(array $meta_data) {
    $this->meta_data = array_merge($this->meta_data, $meta_data);
}

Затем в конструкторах расширяющего класса вы просто передаете массив значений, которые вы хотите добавить к Base::$meta_data.

0 голосов
/ 17 сентября 2014

Вы также можете построить список в конструкторе, если используете статические определения:

class Base {
    public static $meta_data = array('col1','col2');
    function __construct() {
        $this->meta_data = array();
        $class = $this;
        while ($class) {
            $this->meta_data = array_merge($class::$meta_data, $this->meta_data);
            $class = get_parent_class($class);
        }
        print implode(',', $this->meta_data) . "\n";
    }
}

class A extends Base {
    public static $meta_data = array('col3','col4');
}

class B extends A {
    public static $meta_data = array('col5','col6');
}

new A();
new B();

Будет выведено:

col1,col2,col3,col4
col1,col2,col3,col4,col5,col6
0 голосов
/ 03 февраля 2012
class base
{
    public $met;

    function __construct()
    {
    $this->met=array("col1","col2");
//      $this->query= "select " . $this->met " from test"; 
    }
}

class a extends base
{

    public $meta;
    function __construct()
    {
        parent::__construct();
            $this->meta =array("col3", "col4" );
        $this->meta=array_merge((array)$this->meta,(array)$this->met);
        print_r($this->meta);
    }

}

class b extends a
{
public $metb;
    function __construct()
    {
        parent::__construct();
            $this->metb =array("col5", "col6" );
        $this->metb=array_merge((array)$this->meta,(array)$this->met);
        print_r($this->metb);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...