PHPでstaticメソッドを呼ぶ方法として、以下のようにselfを使って呼ぶかなと思います。(もちろんstaticの場合もあると思います)
self::foo()
抽象クラスで定義されたabstract static methodを呼び出す例
ただ、抽象クラスを定義してそこにabstract staticメソッドを作成した場合に、そのメソッドを呼び方として、以下のように書いてしまいました。
<?php abstract class User { protected $name; function __construct($name) { $this->name = $name; } abstract protected static function getJobTitle(): string; public function getName() { return sprintf('%s %s', self::getJobTitle(), $this->name); // ★selfで呼び出す } } class AdminUser extends User { protected static function getJobTitle(): string { return '管理者'; } } $user = new AdminUser('半沢直樹'); echo $user->getName();
サンプルプログラムなので、テキトーに作成したものです。
abstractで宣言した抽象クラスであるUserクラスに getJobTitle()
メソッドを定義します。
この getJobTitle()
メソッドを通常のpublicメソッドである getName()
からselfを用いて呼び出すプログラムです。
実行エラー
これを実行すると・・・
# php app.php Fatal error: Uncaught Error: Cannot call abstract method User::getJobTitle() in /var/www/abstract-static-method/app.php on line 14 Error: Cannot call abstract method User::getJobTitle() in /var/www/abstract-static-method/app.php on line 14 Call Stack: 0.0021 394216 1. {main}() /var/www/abstract-static-method/app.php:0 0.0023 394272 2. AdminUser->getName() /var/www/abstract-static-method/app.php:26
このように、 Fatal error: Uncaught Error: Cannot call abstract method
というエラーが出てしまいます。
staticを用いる
そこで、以下のようにstaticを用いて呼び出してみます。
<?php abstract class User { protected $name; function __construct($name) { $this->name = $name; } abstract protected static function getJobTitle(): string; public function getName() { return sprintf('%s %s', static::getJobTitle(), $this->name); // ★staticで呼び出す } } class AdminUser extends User { protected static function getJobTitle(): string { return '管理者'; } } $user = new AdminUser('半沢直樹'); echo $user->getName();
実行結果
このように修正して実行すると・・・
# php app.php 管理者 半沢直樹
と、無事、呼び出すことができました。
staticとself の違い
では、staticとselfの違いとはなんでしょう?
php static self
とかでググってもらえるとたくさん出ると思うのですが、自分はこの書き方が覚えやすいかもと思いました。
static
は実行時 のクラスを指すself
は定義時 のクラスを指す
参考:PHP の static と self の違い | gotohayato.com
サンプルプログラムで動作確認
以下のようなサンプルプログラムを書いてみました。
<?php class A { protected static function hoge() { return 'parent'; } public function echoByStatic() { echo static::hoge() . PHP_EOL; } public function echoBySelf() { echo self::hoge() . PHP_EOL; } } class B extends A { protected static function hoge() { return 'chile'; } } $b = new B(); echo 'static: '; $b->echoByStatic(); echo 'self: '; $b->echoBySelf();
これの実行結果は以下になります。
# php static-self.php static: chile self: parent
実行結果からもわかりますが、たしかにstaticは実行時のクラスを指し、selfは定義時のクラスを指すことがわかります。
さいごに
ということで、ここからもselfで呼び出すということは、抽象クラスの抽象メソッドを呼び出すということになるので、そりゃエラーになりますね、という結論に自分はなりました。