为什么以及如何将 new 关键字与 class 的现有对象一起使用?
Why and how the new keyword is being used with the already existing object of a class?
我正在使用 PHP 7.1.11
考虑以下代码:
<?php
class Test {
static public function getNew() {
return new static;
}
}
class Child extends Test {}
$obj1 = new Test();
$obj2 = new $obj1;
?>
以上代码片段摘自 PHP 手册。
从上面的代码中,我无法理解 新关键字 为何以及如何与 class Test
?[=15 的现有对象一起使用=]
这样做的目的是什么?
是否推荐新关键字的这种用法?
如果你真的想将一个已经存在的 class 对象分配给某个变量,那么不能通过简单地编写语句 $obj2 = $obj1;
?
来完成吗?
下面两种说法有什么区别?哪个更好,应该首选?
$obj2 = new $obj1;
$obj2 = $obj1;
new
运算符总是创建对象的新实例。它有一个参数,可以是硬编码的 class 名称:
$newObject = new MyClass();
或包含 class 名称的变量:
$className = 'MyClass';
$newObject = new $className();
或者您要创建的对象类型的现有实例:
$oldObject = new MyClass();
$newObject = new $oldObject(); // Same as using "new MyClass();"
您可能永远不会使用第三种情况。
$obj2 = new $obj1;
(创建与 $obj1 相同 class 的对象的新实例)!== $obj2 = $obj1;
(创建 $obj2
对 $ 的引用obj1) !== $obj2 = clone $obj1;
(它创建一个新的 $obj2,它具有与原始对象相同的 属性 值,但作为一个新的对象实例)
对于我在上面的评论中引用的 3 种不同情况,让我们创建一个简单的 class 并实例化它:
class User {
public $firstname;
public $lastname;
public function __construct($firstname = 'TEST', $lastname = 'USER') {
$this->firstname = $firstname;
$this->lastname = $lastname;
}
public function getName() {
return implode(' ', [$this->firstname, $this->lastname]);
}
}
// original instance of a User
$obj1 = new User('Mark', 'Baker');
var_dump($obj1->getName()); // Mark Baker
现在,如果我们简单地为原始变量分配一个新变量,我们就是在设置一个指向原始变量的指针(因为它是一个对象),类似于引用
// Simply set reference to our original User
$obj2 = $obj1;
var_dump($obj2->getName()); // Mark Baker
// And if we change properties of the instance, it changes for both because it's a reference
$obj2->firstname = 'David Mark';
var_dump($obj2->getName()); // David Mark Baker
var_dump($obj1->getName()); // David Mark Baker
对任何一个的任何更改都会反映在另一个中,因为它们指向同一个对象实例
如果我们使用 clone
,那么我们将创建一个全新的对象实例,但已经填充了来自原始
的 属性 值
// Clone the original object, this will create a new instance but will inherit property values of the original
$obj3 = clone $obj1;
var_dump($obj3->getName()); // David Mark Baker
// But changing properties of the clone won't affect the original in any way
$obj3->firstname = 'Mark';
var_dump($obj3->getName()); // Mark Baker
var_dump($obj1->getName()); // David Mark Baker
现在,如果我们更改原始属性,则不会影响克隆(反之亦然),因为它们是唯一实例。
我们有第三种情况,我们使用 new
实例而不是 class 名称。
// Now create a new instance of the same type of object as your original User
// If we had mandatory constructor arguments, then we'd have to provide them $obj4 = new $obj1('a', 'b');
// But because they're optional, we can get away with allowing the defaults
$obj4 = new $obj1;
var_dump($obj4->getName()); // TEST USER
如果我们不知道 class 类型 $obj1
是什么,那也没关系(尽管很容易找到)。这创建了 class $obj1
的全新实例,没有 clone
提供的 属性 继承,也没有像 $obj2 = $obj1
提供的引用...... ..它仍然调用构造函数,所以我们必须传递任何强制构造函数参数(或得到一个错误)。
我正在使用 PHP 7.1.11
考虑以下代码:
<?php
class Test {
static public function getNew() {
return new static;
}
}
class Child extends Test {}
$obj1 = new Test();
$obj2 = new $obj1;
?>
以上代码片段摘自 PHP 手册。
从上面的代码中,我无法理解 新关键字 为何以及如何与 class Test
?[=15 的现有对象一起使用=]
这样做的目的是什么?
是否推荐新关键字的这种用法?
如果你真的想将一个已经存在的 class 对象分配给某个变量,那么不能通过简单地编写语句 $obj2 = $obj1;
?
下面两种说法有什么区别?哪个更好,应该首选?
$obj2 = new $obj1;
$obj2 = $obj1;
new
运算符总是创建对象的新实例。它有一个参数,可以是硬编码的 class 名称:
$newObject = new MyClass();
或包含 class 名称的变量:
$className = 'MyClass';
$newObject = new $className();
或者您要创建的对象类型的现有实例:
$oldObject = new MyClass();
$newObject = new $oldObject(); // Same as using "new MyClass();"
您可能永远不会使用第三种情况。
$obj2 = new $obj1;
(创建与 $obj1 相同 class 的对象的新实例)!== $obj2 = $obj1;
(创建 $obj2
对 $ 的引用obj1) !== $obj2 = clone $obj1;
(它创建一个新的 $obj2,它具有与原始对象相同的 属性 值,但作为一个新的对象实例)
对于我在上面的评论中引用的 3 种不同情况,让我们创建一个简单的 class 并实例化它:
class User {
public $firstname;
public $lastname;
public function __construct($firstname = 'TEST', $lastname = 'USER') {
$this->firstname = $firstname;
$this->lastname = $lastname;
}
public function getName() {
return implode(' ', [$this->firstname, $this->lastname]);
}
}
// original instance of a User
$obj1 = new User('Mark', 'Baker');
var_dump($obj1->getName()); // Mark Baker
现在,如果我们简单地为原始变量分配一个新变量,我们就是在设置一个指向原始变量的指针(因为它是一个对象),类似于引用
// Simply set reference to our original User
$obj2 = $obj1;
var_dump($obj2->getName()); // Mark Baker
// And if we change properties of the instance, it changes for both because it's a reference
$obj2->firstname = 'David Mark';
var_dump($obj2->getName()); // David Mark Baker
var_dump($obj1->getName()); // David Mark Baker
对任何一个的任何更改都会反映在另一个中,因为它们指向同一个对象实例
如果我们使用 clone
,那么我们将创建一个全新的对象实例,但已经填充了来自原始
// Clone the original object, this will create a new instance but will inherit property values of the original
$obj3 = clone $obj1;
var_dump($obj3->getName()); // David Mark Baker
// But changing properties of the clone won't affect the original in any way
$obj3->firstname = 'Mark';
var_dump($obj3->getName()); // Mark Baker
var_dump($obj1->getName()); // David Mark Baker
现在,如果我们更改原始属性,则不会影响克隆(反之亦然),因为它们是唯一实例。
我们有第三种情况,我们使用 new
实例而不是 class 名称。
// Now create a new instance of the same type of object as your original User
// If we had mandatory constructor arguments, then we'd have to provide them $obj4 = new $obj1('a', 'b');
// But because they're optional, we can get away with allowing the defaults
$obj4 = new $obj1;
var_dump($obj4->getName()); // TEST USER
如果我们不知道 class 类型 $obj1
是什么,那也没关系(尽管很容易找到)。这创建了 class $obj1
的全新实例,没有 clone
提供的 属性 继承,也没有像 $obj2 = $obj1
提供的引用...... ..它仍然调用构造函数,所以我们必须传递任何强制构造函数参数(或得到一个错误)。