Проблема с наследованием PHP ООП. Не удается получить доступ к родительской переменной из дочернего класса

#php #oop #inheritance

#php #ооп #наследование

Вопрос:

У меня есть класс, подобный этому:

 class A {

 public $var = "";

 function __construct() {

  $this->var = "value";

 }

}
  

И дочерний класс, подобный этому:

 class B extends A {

 function __construct() {

  // Is this correct?
  parent::__construct();

 }

 function my_function() {

  // Or this?
  // $options is an instantiation of A.
  global $options;

  echo $this->var;

 }

}
  

Проблема, с которой я столкнулся, заключается в том, что когда я вызвал метод my_function(), значение var было пустым. После прочтения на php.net некоторое время я выяснял, что когда дочерний класс имеет свой собственный конструктор, родительский конструктор переопределяется, поэтому моя переменная была пустой. Мой вопрос в том, является ли способ, которым я вызываю parent::__construct(), правильным решением или мне следует просто глобализировать экземпляр объекта, который я создал в своем скрипте? Я много читал в комментариях к PHP.net и в других местах, и я не смог найти ничего краткого.

Комментарии:

1. Я взял ваши точные определения классов, создал экземпляр B и вызвал my_function , и value был напечатан. Это неверно?

Ответ №1:

С помощью parent::method() вы вызываете переопределенный метод (не только конструктор), так что ваше решение правильное. В вашем случае вы можете полностью опустить конструктор и просто задать значение при объявлении свойства.

 class A {
  public $var = "value";
}
  

Дополнительно: глобальные переменные уродливы во всех отношениях. Используйте их только, если у вас есть действительно веские причины для этого, и никогда, потому что так удобнее.

Комментарии:

1. Причина, по которой я устанавливаю эту переменную из конструктора A, заключается в том, что я выполняю некоторые настройки переменных там. У меня есть файл загрузчика, который я включаю в каждую страницу. В файле загрузчика включена моя конфигурация. Класс A считывает файл конфигурации и устанавливает несколько переменных в A. В моем файле loader у меня есть экземпляр A, который я использую на всех страницах для доступа к тем переменным, которые были установлены в A.

Ответ №2:

Следующая «реализация» …

 $instanceOfB = new B();
$instanceOfB->my_function();
  

выдает «значение» … как и ожидалось.

Каким был ваш способ вызова my_function () ?

Комментарии:

1. Я знаю, что это работает. Мой вопрос в том, правильно ли то, что я делаю. Я уже создал экземпляр объекта в своем скрипте следующим образом: $options = new A. Я просто не был уверен, что вызов parent::_construct() в конструкторе дочернего класса был в порядке, поскольку я бы дважды вызывал метод A::__construct() в моем скрипте (один раз с помощью $ options, затем снова в дочернем конструкторе ).

2. А, понятно. 1-е — Я бы рекомендовал объявить ::$var как защищенный, если вы собираетесь получать доступ к этой переменной только через дочерние классы. Public позволил бы любому включенному скрипту изменять значение $ var. 2-й — конструктор A не вызывается дважды, если вы создаете экземпляр $options как new B();. Попробуйте напечатать что-нибудь в конструкторе A … она будет напечатана. Удалите parent::__construct() в конструкторе B: ничего не происходит. Вам не нужно обращаться к ГЛОБАЛЬНОМУ $options в my_function(). Просто используйте унаследованный A …