如何使用__construct中的父工具实例化子类

Vin*_*ent 5 php oop factory

我有一个A类,必须使用其他多个对象进行实例化

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

为了省去这个类实例化的麻烦,我为这个类设置了一个工厂.

class A_Factory{
    public static function create_A(){
        return new A(new X(), new Y(), new Z());
    }
}
Run Code Online (Sandbox Code Playgroud)

我有一个扩展类A的B类.我的问题是我无法弄清楚如何在B类中实例化A类以访问属性'foo'.

我很自然地尝试:

class B extends A{
   function __construct(){
      A_Factory::create_A();  
   }
}
Run Code Online (Sandbox Code Playgroud)

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

Undefined property: A::$foo
Run Code Online (Sandbox Code Playgroud)

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

Fab*_*ler 4

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

父级::__construct()

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

以下代码有效:

(假设foo不是private

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

这个也有效:

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

工厂

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();
Run Code Online (Sandbox Code Playgroud)

这利用了与关键字的后期静态绑定staticstatic解析为被调用类的类名,因此它是AinA::create()Bin B::create()

请注意 的区别,它始终解析为声明self该方法的类(在本例中它将始终为)A