0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-10-06

タイトル変更しました

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

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

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

0
0
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?