
こんにちは。
今回はPythonとPHPのオーバーライドの仕様について書いていこうと思います。
私がPythonを学習した後、PHPを学習した際、オーバーライドの仕様でつまづいたので、メモ代わりに残します。
PythonとPHPの違いに、メソッドの第一引数にself(this)をつけるかつけないかがありますが、それとは別の話をします。
PythonとPHPのオーバーライドの違い
Pytonのオーバーライド
まずはPythonのオーバーライドです。
コードをみてみます。
class Greeting:
def __init__(self):
self.msg1 = "hello"
self.msg2 = "world"
def say_hello(self):
print("{} {}".format(self.msg1, self.msg2))
class Hello(Greeting):
def say_hello(self, msg):
print("{} {}".format(self.msg1, msg))
hoge = Hello()
hoge.say_hello("python")
実行結果は
hello python
となります。
では、次にPythonと同じ記述でPHPのオーバーライドコードを記述します。
間違ったPHPのオーバーライド
<?php
class Greeting {
function __construct() {
$this->msg1 = "hello";
$this->msg2 = "world";
}
function say_hello() {
echo "{$this->msg1} {$this->msg2}\n";
}
}
class Hello extends Greeting {
function say_hello($msg) {
echo "{$this->msg1} {$msg}\n";
}
}
$hoge = new Hello();
$hoge->say_hello("python");
これを実行するとエラーになってしまいます。
なぜでしょうか。
公式ドキュメントを読んでみましょう。
メソッドをオーバーライドするときは、 子クラスのシグネチャが親クラスのそれと互換性がなければいけません。 互換性が壊れた場合、致命的なエラーが発生します。 PHP 8.0.0 より前のバージョンでは、 互換性が壊れた場合に、
E_WARNING
レベルの警告が発生していました。
と書いてあります。
つまり、今回の場合だと、親クラスと子クラスのメソッドの引数が違うためエラーが発生してしまったわけです。
ここが、PythonとPHPのオーバーライドの仕様の違うところですね。
正しいPHPのコードをみてみましょう。
正しいPHPのオーバーライド
<?php
class Greeting {
function __construct() {
$this->msg1 = "hello";
$this->msg2 = "world";
}
function say_hello() {
echo "{$this->msg1} {$this->msg2}\n";
}
}
class Hello extends Greeting {
function say_hello($msg) {
echo "{$this->msg1} {$msg = null}\n";
}
}
$hoge = new Hello();
$hoge->say_hello("python");
おわかりいただけたでしょうか?
違う部分だけ抜き出すと、PHPコード16行目が違いますね。
function say_hello($msg) {
function say_hello($msg = null) {
はい、こんな感じです。
こうすれば、PHPでオーバーライドした場合も正常に動作します。
おわりに
いかがでしたでしょうか。
PythonとPHPのオーバーライドの仕様の違いについて理解していただけたら嬉しいです。

私はTwitterをやっておりますので、フォローして頂けると嬉しいです!!
また、DMにて質問も受け付けております。遠慮なくお聞きください。