概要
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()が呼ばれる。