关于php:我可以从基础工厂方法调用私有子构造函数吗?

Can I call a private child constructor from a base factory method?

我想使用一个私有构造函数来实现以下内容。

问题是,get_class()返回ParentBase;eventhough;get_called_class()返回ChildClass

如何从调用类上下文而不是基类上下文调用u construct()?

会有很多子类,所以我只需要一个共享工厂方法,并且我还要确保子类不能被扩展(这样子类就不能用新关键字创建)。

似乎应该有一种方法让ChildClass::createObject()与私有ChildClass构造函数和公共ParentBase工厂方法一起工作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
class ParentBase
{
    public static function createObject()
    {
        echo get_class() ."<br/>";        // prints ParentBase
        echo get_called_class() ."<br/>"; // prints ChildClass
        return new static();
    }
}

class ChildClass extends ParentBase
{
    private $greeting ="bye";

    private function __construct()
    {
        $this->greeting ="hi";
    }

    public function greet()
    {
        echo $this->greeting;
    }
}

$child = ChildClass::createObject();
$child->greet();

以上输出为:

1
2
3
ParentBase
ChildClass
Fatal error: Call to private ChildClass::__construct() from context 'ParentBase'

受保护的建筑工程:http://codepad.viper-7.com/scgjwa

私有构造函数不:网址:http://codepad.viper-7.com/ybs7iz


这是createObject();的预期行为,是ParentBase的函数,所以它会从get_class()返回ParentBase,但它是从ChildClass调用的,所以它会从get_called_class()返回ChildClass

关于构造器,由于构造器被指定为私有的,所以只能从类中创建对象。通过保护它,现在父类可以创建ChildClass的对象。

可能的解决方案是重写ChildClass中的createObject()类。

1
2
3
4
5
6
7
8
9
class ChildClass extends ParentBase
{
    public static function createObject()
    {
        echo get_class() ."<br/>";
        echo get_called_class() ."<br/>";
        return new static();
    }
}

或者,您可以使构造函数受到保护,然后您将使该构造函数可访问父类,并限制子类的任何子类,使其成为最终类,从而使它只能从父类访问。


如果这是php 5.4……

在玩了其他东西并在PHP OOP上阅读之后。看来性状可以做到这一点。

我喜欢use Trait符号,在这种情况下,很明显应该使用工厂来实例化类。

使用一个特性是有利的,因为它可以在没有共同血统的多个类层次结构中共享工厂特性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php

// NOTE: traits are only avaialable in ** PHP 5.4 **
trait Factory
{
    public static function createObject()
    {
        echo get_class() ."<br/>";        // prints ChildClass
        echo get_called_class() ."<br/>"; // prints ChildClass
        return new static();
    }
}

class ChildClass
{
    use Factory;

    private $greeting ="bye";

    private function __construct()
    {
        $this->greeting ="hi";
    }

    public function greet()
    {
        echo $this->greeting;
    }
}

$child = ChildClass::createObject();
$child->greet();

工作代码示例


据我所知,子构造函数必须受到保护或公开。我遇到了一个类似的问题,因为另一个问题,我试图访问一个私有财产。

但出于某种原因,您的问题"我可以从基本工厂方法调用私有子构造函数吗?"不反映您的代码,所以我建议您编辑它,因为我在如何回答这个问题上遇到了麻烦。