2014-10-11 3 views
1

в попытке улучшить мое понимание ООП, я решил реорганизовать часть своего кода, используя абстрактный класс. Идея примерно такая;PHP Pass экземпляр объекта для абстрактного конструктора классов

  • Один абстрактный «родительский» класс, который формирует базу для всех дочерних классов.
  • Один класс «помощник», который имеет ряд методов, которые потребуются детям абстрактного класса.
  • класс «помощник» будет использоваться другими классами, поэтому я не хочу, чтобы это было неотъемлемой частью абстрактного класса.

Проблема;

Класс child расширяет абстрактный класс по назначению, но PHP дает мне предупреждение о том, что аргумент $helper отсутствует в конструкторе абстрактного класса. Я считаю, что конструктор вызван, потому что в моем дочернем классе нет ни одного, это нормально, но поскольку вы не вызываете прямой вызов абстрактного класса, как мне заставить его работать? Пример кода ниже;

abstract class Parent_Abstract 
{ 
    public $input_helper_methods; 

    public function __construct($helpers = NULL) 
    { 

     //set the helper methods 
     $this->input_helper_methods = $helpers; 

    } 
} 

Переменная $helpers находится в другом файле в тот момент, который входит в верхней части файла с абстрактным классом. Опять же, я думаю, что есть проблема с тем, как это делается. Когда я понимаю структуру, я хотел бы использовать автозагрузчик, но пока просто ручная работа была бы хорошей. Это содержимое этого файла;

class RD_Form_Input_Helper_Methods 
{ 
    private $var = 'something'; 
} 

$helpers = new RD_Form_Input_Helper_Methods; 

Надеюсь, это имеет смысл. Спасибо, что нашли время, чтобы прочитать/ответить.

Другой пример;

//"helper" classes. I would like these methods to be available to Child_One and Child_Two 
class Helper_Functions {} 

class Formatting_Functions {} 


abstract class Parent_Abstract() 
{ 
    private $helper_functions; 
    private $formatting_functions; 

    public function __construct($object_one, object_two) 
    { 
     $this->helper_functions = $object_one; 
     $this->helper_functions = $object_two; 
    } 

} 

class Child_One extends Parent_Abstract 
{ 
    //I can use any of the properties or methods from the Helper_Functions or Formatting_Function class 
} 

class Child_Two extends Parent_Abstract 
{ 
    //I can use any of the properties or methods from the Helper_Functions or Formatting_Function class 
} 
+0

Nope. Я видел ваш ответ в ответе ниже и ответил там. – Dan

ответ

-1

Что вы ищете, это static variables.

В этом примере я использую переменную с именем $text, а не вашим оригиналом $helpers. Переменная, однажды установленная, будет одинаковой во всех дочерних классах.

Определить абстрактный класс с переменной public static. Кроме того, необязательно укажите getter function, это позволит вам получить доступ к значению статической переменной в качестве свойства для каждого дочернего класса.

abstract class Parent_Abstract 
{ 

    public static $text; 

    public function __get($name) 
    { 
     // return the static variable's value 
     return $name == 'text' ? self::$text : null; 
    } 
} 

Определение 2 дочерние классы:

class Child1 extends Parent_Abstract 
{ 

} 

class Child2 extends Parent_Abstract 
{ 

} 

Теперь, чтобы проверить ... Установить значение статической переменной, то инстанцирование дочерние классы и проверить значение $text на каждом объекте;

Parent_Abstract::$text = 'hello world'; 

$child1 = new Child1(); 
$child2 = new Child2(); 

echo $child1->text . "\n"; 
echo $child2->text; 

Вы увидите, что значение для обоих детей одинаково.

+0

Привет, спасибо за ответ. Я уже пробовал это, он работает нормально. Я пытаюсь передать объект $ helpers непосредственно к абстрактному классу, поэтому мне не нужно передавать его через дочерние классы, хотя, я думаю, мне нужно было только его передать один раз? Confusing ... – Dan

+0

@ Dan: Ваш комментарий заставляет меня немного задуматься: * Как * вы передаете '$ helpers' * непосредственно * в абстрактный класс? Абстрактный класс обычно не существует. - но если я верну вас сейчас, вы перейдете туда через наследование ('parent :: ...'), и вы пройдете его только один раз, потому что есть только один объект, а не. это всего лишь соединение абстрактного базового класса и расширяющегося класса, но это один объект. Во время выполнения вы обычно не заботитесь об этом. для приложения нет никакой разницы, если был базовый класс или нет. – hakre

+0

@hakre - Я понимаю идею о том, что абстрактный класс не существует. Может быть, что это моя голова, просто невозможно? Я хотел бы объединить функциональность одного класса с абстрактным классом, а затем наследовать его. – Dan

1

The child class extends the abstract class as intended, but PHP gives me a warning that the $helper argument is missing from the abstract class's constructor.

Вы только получили бы такое предупреждение, если конструктор абстрактного класса требует параметра $helper.Но ваш код отличается, то параметр $helper не является обязательным:

abstract class Parent_Abstract 
{ 
    public $input_helper_methods; 

    public function __construct($helpers = NULL) 
    {       ###############  $helpers is optional 

Теперь, когда я цитирую, он также имеет другое имя $helper =/$helpers =.

Так что, скорее всего, код, который вы приводите в своем вопросе, является неполным и с ошибками.

Давайте просто очертить новый смоделированный ваш вопрос:

abstract class AbstractBaseClass 
{ 
    private $helper; 

    function __construct($helper) 
    { 
     $this->helper = $helper; 
    } 
} 

class Concrete extends AbstractBaseClass 
{ 
} 

различия Вкратце: $helper поле (или свойство) является частной и не общественного; требуется параметр $helper ctor.

Используя этот код и инстанцирование конкретного ChildClass дает свою указанную ошибку:

// Warning: Missing argument 1 for AbstractBaseClass::__construct() 

$obj = new Concrete(); 

Это происходит потому, что помощник отсутствует. Чтобы сделать это очень простым, допустим, что помощник - это действительно секретное число, которое вам нужно в сложных вычислениях, сделанных такими конкретными классами. Номер 42:

$obj = new Concrete(42); 

Ошибка. И поле helper правильно инициализировано:

print_r($obj); 

Concrete Object 
(
    [helper:AbstractBaseClass:private] => 42 
) 

Как вы можете видеть, частного поля абстрактного класса было установлено. Помощник (здесь номер 42) назначен ему.

Смежные вопросы