2017-11-16 15 views
1

私は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と一緒に使用されている理由とその理由を理解できませんか?

このような目的の背景は何ですか?

このような使用方法は、新しいキーワードをお勧めしますか?

クラスの既存のオブジェクトをいくつかの変数に割り当てる場合は、単に文$obj2 = $obj1;を記述するだけで済みませんか?

以下の2つのステートメントの違いは何ですか?どちらが優れていて優先されるべきですか?

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

答えて

4

$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 

彼らは同じオブジェクトインスタンスに


を指しているので、どちらかへの変更は、我々が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をクラス名ではなくインスタンスに使用している3番目のケースがあります。

// 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のような参照もありません。コンストラクタをまだ呼び出すので、必須のコンストラクタ引数を渡す必要があります(getエラー)。

2

newオペレータは常にオブジェクトの新しいインスタンスを作成します。これは、ハードコードされたクラスの名前にすることができます一つの引数を取ります:

$newObject = new MyClass(); 

またはクラス名を含む変数:

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

それとも、希望のタイプのオブジェクトの既存のインスタンス

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

おそらく、第3のケースを使用することはありません。

+0

私が持っている疑いを明確にしてください。あなたの答えでは、「オブジェクトのインスタンス」という言葉を使用しましたが、実際には「オブジェクト自体はクラスのインスタンスです」という言葉を使用しました。そして、あなたはどのようにして/オブジェクトのインスタンス(すでにクラスのインスタンスです)を作る/言うことができますか? – user2839497

+0

セマンティクス。 「オブジェクトのインスタンス」を「インスタンス化されたオブジェクト」に置き換えてください。 –

関連する問題