Help us understand the problem. What is going on with this article?

PHPでもコンストラクタに限り、シグニチャーの違うオーバーライドができる!!

タイトル変更しました

ご指摘いただき、勘違いが分かりましたので、タイトルを以下の通り変更させてもらいました。

PHPでも他のオブジェクト指向で言うオーバーロードができる!!(ただしコンストラクに限る)

PHPでもコンストラクタに限り、シグニチャーの違うオーバーライドができる!!

概要

表題の通りですが、PHPでもコンストラクタに限り引数のシグニチャが異なるオーバーライド(他のオブジェクト指向で言うオーバーロード)ができるというのをマニュアルで確認したというだけのお話です。
PHPではオーバーロードができないという記事をよく見かけるのですが、コンストラクタだけは例外ということが明記されている記事を見かけなかったので(マニュアルにあるから当たり前!?)、残しておこうかと。

[2020-10-06追記]
ご指摘によりオーバーロードはできないことが分かりましたので、以下の記事は、「PHPでもコンストラクタに限り、シグニチャーの違うオーバーライドができる!!」という内容になります。
@error_401 さんありがとうございます!

Manual

PHP Manual(extends)

サンプルコード

class Base
{
        protected $a;
        public function __construct(int $a)
        {
                $this->a = $a;
        }

        public function test(string $a)
        {
                echo sprintf('class Base(%s)', $a) . PHP_EOL;
        }
}

class A extends Base
{
        protected $a;
        protected $b;
        public function __construct(string $a, int $b)
        {
                $this->a = $a;
                $this->b = $b;
                parent::__construct($b);
        }

        public function test(int $a)
        {
                echo sprintf('class A(%d)', $a) . PHP_EOL;
        }
}


$base = new Base(10);
$base->test(10);
$base->test('xxx');

$a = new A('aaa', 10);
$a->test(10);
//$a->test('xxx');

このコードを実行すると、以下のE_WARNINGレベルのエラーが発生しますが、コンストクタについては何もエラーが発生していないことから、コンストラクタのオーバーライドは例外で、正常にオーバーライド(オーバーロード)可能なことが分かります。

Warning: Declaration of A::test(int $a) should be compatible with Base::test(string $a) in /var/www/wonder/test_overload.php on line 32

更なる疑問

ここで気になるのが、コンストラクタ以外のメソッドもWARNINGなので、実行自体は止まらず、オーバーライドできているような挙動となることです。

//$a->test('xxx');

のコメントアウトを外すと、以下のエラーが発生することからもオーバーライドして、引数の型が変更できているように見えます。

Fatal error: Uncaught TypeError: Argument 1 passed to A::test() must be of the type int, string given, called in /var/www/wonder/test_overload.php on line 41 and defined in /var/www/wonder/test_overload.php on line 28

まとめ

以上、新たな疑問は発生しましたが、マニュアル及びE_WARNINGレベルのエラーの発生より、

  • PHPでは引数のシグニチャーが異なるオーバーライド(オーバーロード)は基本的に不可
  • ただしコンストラクタのみオーバーライド(オーバーロード)可能

ということが分かりました。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away