概要
static
、self
はnew
と組み合わせることでクラス内でインスタンスを生成する際に使えるが、以下のような違いがある。
new static
はそれが実行されるときのクラスのインスタンスを生成するnew self
はそれが定義されたときのクラスのインスタンを生成する
準備
以下のようにParentClass
とそれを継承したChildClass
を準備する。
- いずれも同じ名前のインスタンスメソッド
method()
を持つ - それぞれのクラスはスタティックメソッド
parent_method()
、child_method()
を持つ - 何れの内容も同じで、以下を実行する
(new static)->static_method()
(new self)->static_method()
new static
やnew self
はクラスのインスタンスを生成する。この例では()->
で生成されたインスタンスから直接メソッドを呼び出しているが、$instance = new static
のように一旦変数に参照させて$instance->method()
としてもよい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<?php class ParentClass { public static function parent_method() { (new static)->method(); (new self)->method(); } public function method() { echo 'in Parent', PHP_EOL; } } class ChildClass extends ParentClass { public static function child_method() { (new static)->method(); (new self)->method(); } public function method() { echo 'in Child', PHP_EOL; } } |
親クラスのメソッドで生成する場合
親クラスのメソッド内でstatic
、self
で生成されるインスタンスは親クラスのインスタンス。
1 2 3 4 |
ParentClass::parent_method(); // in Parent // in Parent |
子クラスのメソッドで生成する場合
子クラスのメソッド内でstatic
、self
で生成されるインスタンスは子クラスのインスタンス。
1 2 3 4 |
ChildClass::child_method(); // in Child // in Child |
継承元の親クラスのメソッドで生成する場合
子クラスから継承元の親クラスのメソッドを呼んで、その中でstatic
、self
で生成されるインスタンスは以下の通り。
1 2 3 4 |
ChildClass::parent_method(); // in Child // in Parent |
これらは以下のような動作による。
子クラスから呼ばれた親クラスのスタティックメソッドで以下が実行される。
1 2 3 4 5 |
public static function parent_method() { (new static)->method(); (new self)->method(); } |
new static
で生成されるのは、この文が実行されるときにスタティックメソッドを呼び出したChildClass
なので、ChildClass
のインスタンスが生成されて、そのmethod()
が呼ばれる。
new self
で生成されるのは、この文が定義されたParentClass
なので、ParentClass
のインスタンスが生成されて、そのmethod()
が呼ばれる。