php - 为什么以及如何将 new 关键字与类的现有对象一起使用?

我正在使用 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 手册

从上面的代码中,我无法理解 new 关键字 为何以及如何与 class Test 的现有对象一起使用?

这样做的意图是什么?

新关键字的这种用法是否值得推荐?

如果你真的想将一个已经存在的类对象赋值给某个变量,那么难道不能通过简单地编写语句 $obj2 = $obj1; 来完成吗?

下面两个语句有什么区别?哪个更好,应该首选?

$obj2 = new $obj1;
$obj2 = $obj1;

最佳答案

$obj2 = new $obj1; (创建与 $obj1 相同类的对象的新实例)!== $obj2 = $obj1; (这会创建 $obj2 对 $obj1 的引用) !== $obj2 = clone $obj1; (它创建了一个新的 $obj2,其所有属性值都与原始对象相同,但作为一个新的对象实例)

对于我在上面的评论中引用的 3 种不同情况,让我们创建一个简单的类并将其实例化:

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

对任何一个的任何更改都会反射(reflect)在另一个中,因为它们指向同一个对象实例


如果我们使用 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使用实例而不是类名。

// 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

如果我们不知道类类型是什么$obj1是,那么没关系(尽管很容易发现)。这将创建任何类的全新实例 $obj1是,没有属性(property)继承 clone给出,也不是像 $obj2 = $obj1 这样的引用gave.....它仍然调用构造函数,所以我们必须传递任何强制构造函数参数(否则会出错)。

https://stackoverflow.com/questions/47334736/

相关文章:

msbuild - 使用 MSBuild 通过 VS2017 构建 SSDT 项目失败

haskell - `pure x = (\_ -> x)` 是什么意思?

laravel - 批量更新 Laravel 中具有多关系的表

typescript - 为什么 TypeScript 不为接口(interface)生成代码?

reactjs - 文件上传不适用于按钮单击 Material -UI V1 ReactJs

r - 如何从日期获取 ISO 周数

python - 如何计算图像中的亮像素?

batch-file - 在没有出现超时消息的情况下在批处理文件中运行超时命令

r - 计算 R 中分类变量的出现次数

python-2.7 - 我怎么知道我使用的是哪个版本的 Tkinter?