【 PHP 】PHP8に入門してみた 201日目 PHPの基本 ( オブジェクト指向 継承 オーバーライド)

PHP8技術者認定初級試験 が始まるようなので 試験に向けて (できるだけ)勉強しようと思います! 使用する書籍は独習PHP 第4版(山田 祥寛)|翔泳社の本 (shoeisha.co.jp) となります。

オブジェクト指向

オーバーライド

オーバーライド(Override)とは、オブジェクト指向プログラミングにおいて、スーパークラス(親クラス)で定義されたメソッドをサブクラス(子クラス)で再定義することを指します。

具体的には、同じ名前、引数リスト、戻り値の型を持つメソッドをサブクラスで定義することで、スーパークラスで定義されたメソッドを上書きすることができます。

オーバーライドを使うことで、スーパークラスで定義されたメソッドをサブクラスでカスタマイズしたり、サブクラスでの処理をスーパークラスでの処理とは異なるものにしたりすることができます。

また、オーバーライドされたメソッドは、サブクラスのインスタンスで呼び出された場合には、サブクラスで定義されたメソッドが呼び出されます。

ここが重要な部分です。


class SuperClass {
    public function printMessage() {
        echo "Hello from SuperClass\n";
    }
}

class SubClass extends SuperClass {
    public function printMessage() {
        echo "Hello from SubClass\n";
    }
}

上記のように実装して

$sub = new SubClass();
$sub->printMessage();

とするとHello from SubClassと出力されます。

親のメソッドは消滅しちゃうの!?

オーバーライドによって、子クラスで再定義されたメソッドは、親クラスで定義された同じ名前のメソッドを上書き(オーバーライド)しますが、子クラスからでも親クラスのメソッドを呼び出すことは可能です。親クラスのメソッドを呼び出す場合には、parent::を使用します。

先ほどのPHPの例において、SubClassでオーバーライドされたprintMessageメソッドから、SuperClassで定義されたprintMessageメソッドを呼び出すには以下のように記述すればよいようです。


class SubClass extends SuperClass {
    public function printMessage() {
        // オーバーライドされた処理
        echo "Hello from SubClass\n";
        
        // 親クラスの処理を呼び出す
        parent::printMessage(); // ★
    }
}

制約

オーバーライドにはいくつかの制約があります。例えば、以下のような制約が挙げられます。

  • オーバーライドするメソッドは、親クラスのメソッドと同じシグネチャ(メソッド名、引数の数と型、戻り値の型)を持つ必要がある。
  • 親クラスのメソッドがfinalで宣言されている場合は、オーバーライドできない。
  • 親クラスでアクセス制御がprivateに設定されているメソッドは、子クラスからはアクセスできないため、オーバーライドもできない。

オーバーライドが可能なのは、親クラスで宣言されているメソッドであり、シグネチャが同じで、かつアクセス可能な場合に限ります。

しかし、オーバーライドすることができるメソッドの内容は、子クラスが自由に書き換えることができます。

そのため、オーバーライドは、継承を利用した柔軟なプログラム設計において重要な役割を果たします。

メモ

Javaとは違うよコンストラクタ

ここでコンストラクタの話題です。

PHPにおいては、子クラスのコンストラクタが明示的に親クラスのコンストラクタを呼び出すまで、親クラスのコンストラクタは自動的に呼び出されません。

具体的には、以下のようにparent::__construct()を子クラスのコンストラクタ内で呼び出すことで、親クラスのコンストラクタを呼び出します。


class ParentClass {
    public function __construct() {
        echo "ParentClass constructor\n";
    }
}

class ChildClass extends ParentClass {
    public function __construct() {
        parent::__construct();
        echo "ChildClass constructor\n";
    }
}

PHP7.4の前後

PHP7.4からは、オーバーライドの制限が緩和されました。具体的には、オーバーライドするメソッドの引数の型を緩和することができるようになりました。これは、より柔軟なオブジェクト指向プログラミングを可能にします。

PHP7.4以前では、オーバーライドするメソッドの引数の型は、親クラスのメソッドと完全に一致する必要がありました。つまり、親クラスで引数がint型で宣言されているメソッドを、子クラスでstring型の引数を受け取るようにオーバーライドすることはできませんでした。

つまりPHP7.4からのオーバーライドの緩和は、Javaのオーバーライドと似たような機能となっています。

Javaでも、親クラスで定義されたメソッドを子クラスでオーバーライドする場合、オーバーライドするメソッドの引数の型や数は親クラスと同じである必要がありました。
しかし、Java5以降では、引数の型や数が異なる場合でも、メソッド名が同じであればオーバーライドすることができるようになりました。PHP7.4以降も、引数の型や数が異なっていても、メソッド名が同じであればオーバーライドすることができるようになったため、Javaと似たような機能となりました。

PHPPHP

Posted by raika@blog