PHP
 Computer >> コンピューター >  >> プログラミング >> PHP

PHPのfinalクラスとfinalメソッドの使い方を徹底解説

はじめに

「final」キーワードは、PHP 5から導入されたオブジェクト指向プログラミングに関連する機能です。finalを使うことで、クラスの継承やメソッドのオーバーライドを禁止できます。

finalを理解するための前提知識:継承とは

finalを学ぶ前に、「継承(インヘリタンス)」の概念をしっかり理解しておく必要があります。

継承とは、既存のクラス(親クラス)をもとに、新しいクラス(子クラス)を作成する仕組みです。子クラスは親クラスのプロパティやメソッドを受け継ぎます。さらに、子クラス側で親クラスのメソッドを再定義(オーバーライド)することで、元の動作を上書きすることも可能です。

しかし、場合によっては「クラスを継承されたくない」「メソッドをオーバーライドされたくない」というケースもあります。こうした制御を実現するのがfinalキーワードです。クラスやメソッドの先頭にfinalを付けることで、finalクラスを継承しようとしたり、finalメソッドをオーバーライドしようとしたりした時点で、PHPが致命的なエラー(Fatal Error)を発生させます。

注意点

finalキーワードを使用できるのは、クラスとメソッドのみです。プロパティに対してfinalを指定することはできません。

それでは、以下のサンプルコードで具体的な動作を確認していきましょう。

例1:finalメソッドは子クラスでオーバーライドできない

親クラスのメソッドにfinalを付けると、子クラスからそのメソッドを上書きすることはできません。

<?php
    class BaseClass {
        final function calculate($val1, $val2) {
            $sum = $val1 + $val2;
            echo "Sum of given no=" . $sum;
        }
    }
    class ChildClass extends BaseClass {
        // 親クラスのfinalメソッドをオーバーライドしようとしている
        function calculate($x, $y) {
            $mult = $val1 * $val2;
            echo "Multiplication of given no=" . $mult;
        }
    }
    $obj = new ChildClass();
    $obj->calculate(10, 10);
?>

出力結果

PHP Fatal error:  Cannot override final method BaseClass::calculate()

解説

この例では、親クラスであるBaseClassのcalculate()メソッドにfinalが付けられています。これにより、calculate()メソッドはどの子クラスでもオーバーライドできなくなります。

しかし、ChildClassはfinalメソッドであるcalculate()を再定義しようとしているため、PHPは致命的なエラー(Fatal Error)を出力します。つまり、親クラスのfinalメソッドは、子クラスで定義し直すことができないということです。

例2:finalクラスは継承できない

次に、クラス宣言の前にfinalキーワードを付けた例を見てみましょう。

<?php
    final class BaseClass {
        function printData($val1, $val2) {
            $add = $val1 + $val2;
            echo "Sum of given no=" . $add;
        }
    }
    // finalクラスを継承しようとしている
    class Child extends BaseClass {
        function printData($val1, $val2) {
            $m = $val1 * $val2;
            echo "Multiplication of given no=" . $m;
        }
    }
    $obj = new Child();
    $obj->printData(20, 20);
?>

出力結果

PHP Fatal error:  Class Child may not inherit from final class (BaseClass)

解説

この例では、BaseClassがfinalクラスとして定義されています。そのため、BaseClassを継承して新しいクラスを作成することはできません。

ChildクラスがBaseClassをextends(継承)しようとした時点で、PHPは「Class Child may not inherit from final class (BaseClass)」というエラーメッセージを出力します。これは、finalクラスには一切の子クラスを作れないことを意味します。

まとめ

finalキーワードを使うことで、次の2つの制御が可能になります。

  • finalメソッド:子クラスでのオーバーライドを禁止できる
  • finalクラス:クラス自体の継承を禁止できる

ライブラリやフレームワークの開発など、外部からの意図しない変更を防ぎたい場面でfinalは非常に有効です。ただし、使いすぎると拡張性が損なわれるため、設計の意図に応じて適切に活用しましょう。

  1. Javaのstaticとfinalの違いを徹底解説!使い分けのポイントまとめ

    Javaプログラミングにおいて、staticとfinalはどちらも非常によく使われるキーワードですが、それぞれの役割や挙動はまったく異なります。この記事では、両者の違いをわかりやすく整理し、正しく使い分けるためのポイントを解説します。 staticキーワードとは staticは、クラスレベルで共有されるメンバーを定義するためのキーワードです。インスタンスを生成しなくてもアクセスできる点が大きな特徴です。 staticの主な特徴 ネストされたクラス(内部クラス)、変数、メソッド、初期化ブロックに適用できます。 宣言時に必ずしも初期化する必要はありません。 変数の値は後から再代入(再初期化)

  2. Pythonのメソッドチェーンとは?クラスでの実装方法をわかりやすく解説

    メソッドチェーン(Method Chaining)とは メソッドチェーンとは、同じオブジェクトに対して複数のメソッドを連続して呼び出すテクニックです。オブジェクトへの参照を一度書くだけで済むため、コードが簡潔になり、可読性も向上します。 基本的な考え方 例として、barとbazという2つのメソッドを持つクラスFooを考えてみましょう。まず、クラスFooのインスタンスを作成します。 foo = Foo() メソッドチェーンを使わない場合、オブジェクトfooに対してbarとbazの両方を呼び出すには、次のように記述します。 foo.bar() foo.baz() 一方、メソッドチェーンを使えば、次