Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 为什么以及如何将new关键字用于类的现有对象?_Php_Class_Object_New Operator - Fatal编程技术网

Php 为什么以及如何将new关键字用于类的现有对象?

Php 为什么以及如何将new关键字用于类的现有对象?,php,class,object,new-operator,Php,Class,Object,New Operator,我使用的是PHP7.1.11 考虑以下代码: <?php class Test { static public function getNew() { return new static; } } class Child extends Test {} $obj1 = new Test(); $obj2 = new $obj1; ?> new操作符始终创建对象的新实例。它有一个参数,可以是硬编码的类名: $newObject =

我使用的是PHP7.1.11

考虑以下代码:

<?php
  class Test {
    static public function getNew() {
      return new static;
    }
  }

  class Child extends Test {}

  $obj1 = new Test();
  $obj2 = new $obj1;
?>

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

$newObject = new MyClass();
$className = 'MyClass';
$newObject = new $className();
或包含类名的变量:

$newObject = new MyClass();
$className = 'MyClass';
$newObject = new $className();
或要创建的类型的对象的现有实例:

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

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

$obj2=new$obj1(创建与$obj1属于同一类的对象的新实例)!=<代码>$obj2=$obj1(它创建对$obj1的引用)!==<代码>$obj2=克隆$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
对其中一个的任何更改都将反映在另一个中,因为它们指向同一个对象实例


如果我们使用
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
提供的属性继承,也不是像
$obj2=$obj1
提供的引用。。。。。它仍然调用构造函数,因此我们必须传递任何强制构造函数参数(或得到一个错误)。

请澄清我的一个小疑问。在您的答案中,您使用了术语“对象的实例”,但实际上“对象本身是类的实例”。那么,如何生成/说“对象的实例(已经是类的实例)”?语义。如果有帮助,请将“对象实例”替换为“实例化对象”。