gpt4 book ai didi

php - 如何在 __construct 中使用其父工厂实例化子类

转载 作者:可可西里 更新时间:2023-11-01 13:53:23 25 4
gpt4 key购买 nike

我有一个必须使用其他倍数对象实例化的 A 类

class A{
function __construct(new X(), new Y(), new Z()){
$this->foo = 'foo';
}
}

为了省去这个类实例化的麻烦,我为这个类建立了一个工厂。

class A_Factory{
public static function create_A(){
return new A(new X(), new Y(), new Z());
}
}

我有一个扩展类 A 的类 B。我的问题是我不知道如何在 B 类中实例化 A 类以访问属性“foo”。

我觉得尝试很自然:

class B extends A{
function __construct(){
A_Factory::create_A();
}
}

但在尝试访问对象 A 属性时会生成通知错误:

Undefined property: A::$foo

如何使用 A 类工厂在其子类中轻松实例化 A?谢谢。

最佳答案

你尝试使用A_Factory::create_A()与使用 parent::__construct() 的方式相同.然而,这是两个完全不同的调用。

parent ::__构造()

parent解析为 A .当前对象$thisA 的实例(因为 B 的每个实例也是 A 的实例,由于继承)。在这种情况下,调用不是静态调用,尽管运算符 ::已被使用($this 保持不变)。

以下代码有效:

(鉴于 foo 不是 private )

class B extends A
{
function __construct()
{
parent::__construct(new X, new Y, new Z);
echo $this->foo;
}
}

这个也行:

class B extends A
{
function __construct()
{
A::__construct(new X, new Y, new Z);
echo $this->foo;
}
}

工厂

A_Factory::createA()是一个静态调用,因为A_Factory不在 B 的继承树中.还有 A_Factory 创建返回 A 的新实例.所以一旦它被调用,你就有了两个不同的对象:$this还是那个不变的B实例并且您创建了一个不同的实例 A没有将其分配给任何变量。

一种可能的方法是将工厂方法移动到 A 中本身。

这将起作用:

class A
{
function __construct(X $x, Y $y, Z $z)
{
$this->foo = 'foo';
}
public static function create()
{
return new static (new X, new Y, new Z);
}
}

class B extends A
{
}

// Instantiating:
$a = A::create();
$b = B::create();

这利用了 late static bindingstatic关键词。 static解析为被调用类的类名,因此它是 AA::create()BB::create() .

注意与self 的区别,它总是解析为方法被声明的类(在这种情况下它总是 A )

关于php - 如何在 __construct 中使用其父工厂实例化子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32542342/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com