如何在PHP中实现拷贝构造函数?
How to implement a copy constructor in PHP?
我有一个 class 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.
}
我需要为此实现一个复制构造函数class,以便可以通过从另一个帐户复制数据来构建一个新帐户。
在其他 OOP 语言中,这可以通过为默认构造函数创建重载以接收帐户的另一个实例 class 进行复制来完成。但是,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
回调函数。但是,我正在寻找实现复制构造函数的方法,而不是变通方法。
您有 2 个选择:
- 创建 1 个构造函数并检查参数以弄清楚意图是什么。
- 创建工厂方法。您可以在同一个 class 中或在 class.
之外以静态方法的形式执行此操作
我认为 #2 更好,因为您仍然可以通过键入获得好处 + 您可以使用非常有意的措辞来命名方法。
PHP不支持函数重载。
PHP 不支持方法重载,并且不能为 class.
创建多个构造函数
实现所需功能的常用方法是实现 so-called "named constructor",这只是一个静态工厂方法:
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.
}
阅读 this article 了解更多示例。
为什么 __clone
功能对您不起作用?
您可以像这样克隆一个对象,默认的__clone
函数将所有变量复制到新实例。
$a = new Account(....);
$b = clone $a;
但是如果您不想复制所有变量,那么您可以覆盖 class
中的 __clone 函数
class Account {
....
public function __clone() {
$this->type = null;
....
}
}
我有一个 class 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.
}
我需要为此实现一个复制构造函数class,以便可以通过从另一个帐户复制数据来构建一个新帐户。
在其他 OOP 语言中,这可以通过为默认构造函数创建重载以接收帐户的另一个实例 class 进行复制来完成。但是,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
回调函数。但是,我正在寻找实现复制构造函数的方法,而不是变通方法。
您有 2 个选择:
- 创建 1 个构造函数并检查参数以弄清楚意图是什么。
- 创建工厂方法。您可以在同一个 class 中或在 class. 之外以静态方法的形式执行此操作
我认为 #2 更好,因为您仍然可以通过键入获得好处 + 您可以使用非常有意的措辞来命名方法。
PHP不支持函数重载。
PHP 不支持方法重载,并且不能为 class.
创建多个构造函数实现所需功能的常用方法是实现 so-called "named constructor",这只是一个静态工厂方法:
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.
}
阅读 this article 了解更多示例。
为什么 __clone
功能对您不起作用?
您可以像这样克隆一个对象,默认的__clone
函数将所有变量复制到新实例。
$a = new Account(....);
$b = clone $a;
但是如果您不想复制所有变量,那么您可以覆盖 class
中的 __clone 函数class Account {
....
public function __clone() {
$this->type = null;
....
}
}