Слияние свойств родительского и дочернего классов - PullRequest
3 голосов
/ 16 февраля 2011

Я пытаюсь объединить свойство в абстрактном родительском классе с тем же свойством в дочернем классе.Код выглядит примерно так (за исключением моей реализации, рассматриваемое свойство является массивом, а не целым числом):

abstract class A {  
   public $foo = 1;  

   function __construct() {
       echo parent::$foo + $this->foo;    # parent::$foo NOT correct  
   }  
}  

class B extends A {
    public $foo = 2;  
}  

$obj = new B();  # Ideally should output 3  

Теперь я понимаю, что parent :: $ foo в конструкторе не будет работатькак и предполагалось, но как можно объединить значения свойств без жесткого кодирования значения в конструкторе или создания дополнительного свойства в родительском классе?

Ответы [ 3 ]

3 голосов
/ 21 апреля 2012

В конструкторе вашего родительского класса сделайте что-то вроде этого:

<?php

abstract class ParentClass {
    protected $foo = array(
        'bar' => 'Parent Value',
        'baz' => 'Some Other Value',
    );

    public function __construct( ) {
        $parent_vars = get_class_vars(__CLASS__);
        $this->foo = array_merge($parent_vars['foo'], $this->foo);
    }

    public function put_foo( ) {
        print_r($this->foo);
    }
}

class ChildClass extends ParentClass {
    protected $foo = array(
        'bar' => 'Child Value',
    );
}

$Instance = new ChildClass( );
$Instance->put_foo( );
// echos Array ( [bar] => Child Value [baz] => Some Other Value )

По сути, магия исходит от функции get_class_vars( ), которая будет возвращать свойства, которые были установлены в этом конкретном классе, независимо от значений, установленных в дочерних классах.

Если вы хотите получить значения ParentClass с помощью этой функции, вы можете выполнить одно из следующих действий из самого ParentClass: get_class_vars(__CLASS__) или get_class_vars(get_class( ))

Если вы хотите получить значения ChildClass, вы можете сделать следующее из ParentClass или ChildClass: get_class_vars(get_class($this)), хотя это то же самое, что просто получить доступ к $this->var_name (очевидно, это зависит от области видимости переменной) .

3 голосов
/ 16 февраля 2011

Вы не можете сделать это напрямую. Вам необходимо определить его в конструкторе B, поскольку B->$foo перезапишет A во время компиляции (и, следовательно, A->$foo будет потеряно):

abstract class A {  
    public $foo = 1;  
    function __construct() {
        echo $this->foo;
    }  
}  

class B extends A {
    public function __construct() {
        $this->foo += 2;
    }
}

Теперь, есть способы обойти это, но они включают Reflection и будет грязным. Не делай этого. Просто увеличьте его в конструкторе и сделайте ...

0 голосов
/ 16 февраля 2011

Вы не можете. Лучший вариант, который у вас есть, это иметь другую собственность. Я знаю, что вы уже знаете это, но это лучшее решение.

<?php
class A {
    protected $_foo = 2;
}

class B extends A {
    protected $foo = 3;
    function bar( ) {
        return $this->_foo + $this->foo;
    }
}

Это ваша лучшая ставка.

...