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

时间:2017-11-16 16:31:12

标签: php class object new-operator

我正在使用 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 keyword class Test的现有对象一起使用?

这样做的目的是什么?

是否建议使用新关键字

如果你真的想将一个已经存在的类对象分配给某个变量,那么只需编写语句$obj2 = $obj1;就不能这样做吗?

以下两个陈述之间有什么区别?哪一个更好,应该是首选?

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

2 个答案:

答案 0 :(得分:4)

$obj2 = new $obj1;(创建与$ obj1相同的类的对象的新实例)!== $obj2 = $obj1;(创建$obj2对$ obj1的引用)!== { {1}}(它创建一个新的$ obj2,它具有与原始属性值相同的所有属性值,但作为新的对象实例)

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

$obj2 = clone $obj1;

现在,如果我们只是为原始分配一个新变量,我们设置一个指向原始变量的指针(因为它是一个对象),类似于一个参考

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

如果我们不知道类型// 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给出的属性继承,也不像clone给出的引用.....它仍然调用构造函数,所以我们必须传递任何强制构造函数参数(或得到错误)。

答案 1 :(得分:2)

new运算符始终创建对象的新实例。它需要一个参数,它可以是一个硬编码的类名:

$newObject = new MyClass();

或包含类名的变量:

$className = 'MyClass';
$newObject = new $className();

或者您要创建的类型的对象的现有实例:

$oldObject = new MyClass();
$newObject = new $oldObject(); // Same as using "new MyClass();"

你可能永远不会使用第三种情况。