существует ли способ пересечь объект получить данные родительского объекта? С "родительским объектом" я не имею в виду родительского класса, но буквально возражаю. Здесь пример, в javascripty мире :-):
$parent->test = "hello world!";
$parent->child = new B();
Было бы замечательно, Если я мог бы получить доступ ко всем данным из родителя в дочернем объекте:
class B{
//I know this doesn't exists, but it's what I wanted do do
function B(){
$this->parent = $this->parent();
echo $this->parent->test; //it would ouput "hello world"
}
}
На данный момент мое решение состоит в том, чтобы передать родительский объект ребенку (как ссылка) или сделать родителя глобальным. У Вас есть какое-либо лучшее решение?
Спасибо!
Невозможно вызвать
$parent->test = "hello world!";
$parent->child = new B();
и автоматически получить ссылку на $ parent в B.
Обычно существует четыре способа структурировать классы:
1. Агрегируйте родительский объект с помощью инъекции, например
class B
{
private $parent;
public function __construct($parent)
{
$this->parent = $parent;
}
public function setParent($parent)
{
$this->parent = $parent;
}
public function accessParent()
{
$this->parent->someMethodInParent();
}
}
Используйте внедрение конструктора, когда объект должен иметь родительский элемент при его создании. Это отношение имеет-, и оно создает очень слабую связь. В B нет жестко запрограммированных зависимостей, поэтому вы можете легко заменить родительский экземпляр, например, с помощью Mock при UnitTesting. Использование внедрения зависимостей сделает ваш код более удобным в сопровождении.
В вашем сценарии использования вы должны передать $ parent
в B при создании B:
$parent->child = new B($parent);
2. Использовать композицию
class B
{
private $parent;
public function __construct()
{
$this->parent = new Parent;
}
public function accessParent()
{
$this->parent->someMethodInParent();
}
}
Это также отношение has-a , но связывает родительский класс с B. Это также не существующий родительский экземпляр, а новый экземпляр. Судя по формулировке, мне кажется несколько странным, что родитель создан ребенком. Используйте это, когда зависимость - это класс, который не считается существующим вне корневого класса, но является частью всего, что он представляет.
Для вашего UseCase нет способа выполнить $ parent-> child = new B ();
и узнать, какой родитель является при использовании этого подхода, если только $ parent не является синглтоном. Если это так, вы можете получить экземпляр Singleton, например Parent :: getInstance ()
, чтобы добиться желаемого, но учтите, что синглтоны не всем любимый шаблон, например трудно проверить.
3. Использовать наследование
class B extends Parent
{
public function accessParent()
{
$this->someMethodInParent();
}
}
Таким образом вы создаете отношение is-a .Все общедоступные и защищенные методы и свойства родительского класса (но не конкретного экземпляра) будут доступны в B, и вы можете получить к ним доступ через ключевое слово $ this
экземпляра B.
Для вашего UseCase этот подход не работает, так как вам вообще не нужно иметь экземпляр Parent, но B инкапсулирует все Parent при его создании
$b = new B;
4. Используйте ключевое слово global
class B extends Parent
{
private $parent;
public function __construct()
{
global $parent;
$this->parent = $parent;
}
public function accessParent()
{
$this->parent->someMethodInParent();
}
}
Ключевое слово global
импортирует глобальные переменные в текущую область. В общем, вам следует избегать использования глобального ключевого слова в объектно-ориентированном контексте, но использовать один из трех других методов, описанных выше, предпочтительно первый. Несмотря на то, что это языковая функция, она не одобряется - хотя это следующая вещь, которая ближе всего к первой, например
$parent->child = new B();
В любом случае, надеюсь, что это поможет.
Я почти уверен, что в PHP нет чего-то подобного.
Ваше решение передачи родительского объекта -объект для ребенка - лучшее решение, я думаю. Вам следует подумать о том, чтобы установить свойство Parent только в конструкторе дочернего элемента, чтобы не допустить, чтобы у нескольких родителей был один и тот же ребенок.
Нет.
Вы можете получить доступ к переменным из суперкласса, используя $ this:
<?php
class A {
public function __construct()
{
$this->foo = 'hello';
}
}
class B extends A {
public function printFoo()
{
echo $this->foo;
}
}
$b = new B();
$b->printFoo();
?>
Передача родитель для ребенка - лучшее решение. Хотя это несколько нежелательные симбиотические отношения.
Должен ли B () знать об объекте, атрибутом которого он является? Скорее всего, нет. Они лишь слабо связаны через композицию.
Почему B () должен быть атрибутом своего родителя? Вам нужна эта реализация в B () или она должна быть частью родительского?