2

我有一个Account具有默认构造函数的类:

class Account {

    AccountType $type;
    AccountLabel[] $labels;
    AccountAttribute[] $attributes;

    // Initializes a new account and assigns labels to the new account.
    public function __construct(
        AccountType $type,
        AccountLabel[] $labels,
        AccountAttribute[] $attributes)
    {
        $this->type = $type;
        $this->labels = $labels;
        $this->attributes = $attributes;
    }

    // Other parts of the class are omitted here.
}

我需要为此类实现一个复制构造函数,以便可以通过从另一个帐户复制数据来构造一个新帐户。

在其他 OOP 语言中,这可以通过为默认构造函数创建重载来接收帐户类的另一个实例进行复制。但是,PHP 不允许有两个具有相同名称的函数,无论参数是否不同,包括__construct()函数。

我不能将$labels参数设为可选,因为它实际上是创建新帐户所必需的。仅添加新参数使其成为可选可能会导致许多误报测试结果。所以,这个实现应该是最后的手段:

class Account {

    AccountType $type;
    AccountLabel[] $labels;
    AccountAttribute[] $attributes;

    // Initializes a new account and assigns labels to the new account;
    // Or, copy from another account.
    public function __construct(
        AccountType $type,
        AccountLabel[] $labels,
        AccountAttribute[] $attributes,
        Account $that)
    {
        if ($that === null) {
            $this->type = $type;
            $this->labels = $labels;
            $this->attributes = $attributes;
        } else
        {
            // Copy from another account.
            $this->type = $that->type;
            $this->labels = $that->labels;
            $this->attributes = $that->attributes;
        }
    }

    // Other parts of the class are omitted here.
}

我也知道神奇的__clone回调函数。但是,我正在寻找实现复制构造函数的方法,而不是解决方法。

4

3 回答 3

4

PHP 不支持方法重载,并且不能为一个类创建多个构造函数。

实现所需的一种常见方法是实现所谓的“命名构造函数”,它只是一个静态工厂方法:

class Account {

    AccountType $type;
    AccountLabel[] $labels;
    AccountAttribute[] $attributes;

    // The regular constructor
    public function __construct(
        AccountType $type,
        AccountLabel[] $labels,
        AccountAttribute[] $attributes,
    {
        $this->type = $type;
        $this->labels = $labels;
        $this->attributes = $attributes;
    }

    // A "named constructor" that works similar to a copy constructor 
    public static copyFrom(Account $account)
    {
        // Do not re-implement the constructor
        return new self($account->type, $account->labels, $account->attributes);
    }

    // Other parts of the class are omitted here.
}

阅读本文以获取更多示例。

于 2018-03-25T19:48:39.377 回答
1

您有 2 个选项:

  1. 创建 1 个构造函数并检查参数以确定意图是什么。
  2. 创建工厂方法。您可以将其作为同一类中或类外的静态方法来执行。

我认为 #2 更好,因为您仍然可以从键入 + 中受益,您可以使用非常有意识的措辞方法名称。

PHP 不支持函数重载。

于 2018-03-25T19:40:13.933 回答
1

为什么该__clone功能对您不起作用?

您可以像这样克隆对象,默认__clone函数将所有变量复制到新实例。

$a = new Account(....);
$b = clone $a;

但是如果你不想复制所有变量,那么你可以覆盖类中的 __clone 函数

class Account {
    ....
    public function __clone() {
        $this->type = null;
        ....
    }
}
于 2018-03-25T19:53:40.607 回答