【PHP】オーバーライド - スーパークラスのメソッドをサブクラスで再定義する

【PHP】オーバーライド - スーパークラスのメソッドをサブクラスで再定義する

クラスの継承にはオーバーライドと呼ぶ仕組みがあります。

オーバーライドを知ることでサブクラスでスーパークラスのメソッドを再定義することができます。

ここでは、オーバーライドについて解説します。

検証環境

オーバーライド

オーバーライドは“サブクラスでスーパークラスのメソッドを再定義すること”です。

一般的にスーパークラスのメソッドと意味は同じであるが、処理が異なる場合に使用します。

基本構文

オーバーライド(メソッドの再定義)するには、スーパークラスの対象メソッドと同じ名前、同じ引数のメソッドをサブクラスで定義します。

class サブクラス名 extends スーパークラス名 {
    アクセス修飾子 function メソッド名( 仮引数1, 仮引数2 ... ) {
        処理
        return 戻り値;
    }
}

サンプル

オーバーライドを使うコードと使わないコードを比較して動作を確認します。

初めにオーバーライドを使わないコードをご覧ください。

<?php

// 人間クラス
class Person {
    
    // 名前
    public $name;
    
    // あいさつ
    public function greeting() {
        echo "Hey!\n";
        echo "My name is ". $this->name . ".\n";
    }
    
}

// 教師クラス
class Teacher extends Person {
    
    // 担当科目
    public $subject;
    
}

$teacher = new Teacher();
$teacher->name = 'TANAKA';
$teacher->subject= 'Programming';

$teacher->greeting();

?>
$ php sample.php
Hey!
My name is TANAKA.

TeacherクラスはPersonクラスを継承しています。

29行目では、スーパークラスのgreetingメソッドが呼び出されています。

このgreetingメソッドをTeacherクラスでオーバーライドする例は次のとおりです。

<?php

// 人間クラス
class Person {
    
    // 名前
    public $name;
    
    // あいさつ
    public function greeting() {
        echo "Hey!\n";
        echo "My name is ". $this->name . ".\n";
    }
    
}

// 教師クラス
class Teacher extends Person {
    
    // 担当科目
    public $subject;
    
    // あいさつ
    ___ih_diff_start
+    public function greeting() {
+        echo "Hello.\n";
+        echo "I'm a " . $this->name . ", a " . $this->subject . " instructor.\n";
+    }
    ___ih_diff_end
    
}

$teacher = new Teacher();
$teacher->name = 'TANAKA';
$teacher->subject= 'Programming';

$teacher->greeting();

?>
$ php sample.php
Hello.
I'm a TANAKA, a Programming instructor.

24〜27行目でgreetingメソッドをオーバーライドしました。

その他のコードは変わりませんが、実行結果に変化があり、その内容からオーバーライドしたメソッドの処理が実行されたことが分かります。

このようにサブクラスでスーパークラスのメソッドをオーバーライド(再定義)することが可能です。

アクセス修飾子の制限

アクセス修飾子がprivateなプロパティメソッドはオーバーライドできません。

サブクラスでアクセス修飾子がprivateなスーパークラスのメソッドと同名のメソッドを定義すると、オーバーライド(再定義)ではなく“新しいメソッドの定義”とみなされます。

アクセス修飾子については別途解説しますが、ここでは、publicまたはprotectedなメソッドのみオーバーライドが可能であることを覚えておきましょう。

演習問題

問題1

次の実行結果になるプログラムを作成してください。
なお、下記条件を満たすものとします。

  • 下記表の3つのクラスを作成する
  • 実行結果になるように各クラスのインスタンスを使う
クラス 英記 継承元 フィールド メソッド
チケットクラス Ticket なし $price(料金) info()
→ $priceの値を出力
ライブチケット LiveTicket Ticket $place(場所) info()
→ 場所と料金を出力
ライブ配信チケット LiveStreamingTicket Ticket $url(URL) info()
→ URLと料金を出力
===== チケット    =====
料金 : 5000円
===== ライブチケット =====
料金 : 8000円
場所 : ライブハウス
===== ライブ配信   =====
料金 : 3000円
URL : https://it-hack.net/live-streaming

問題2

次の実行結果になるプログラムを作成してください。
なお、下記条件を満たすものとします。

  • 下記表の3つのクラスを作成する
  • 実行結果になるように各クラスのインスタンスを使う
クラス 英記 継承元 フィールド メソッド
車クラス Car なし $distance(移動距離)
※ 初期値は0
$acceleration(加速度)
※ 初期値は60
display_distance()
→ $distanceの値を出力
run_distance()
→ 前進距離を計算
→ 計算式は$acceleration * 1.0
run()
→ run_distance()で前進距離を取得し出力する。また、$distanceに前進距離を加算
スポーツカークラス SportCar Car なし run_distance()
→ 前進距離を計算
→ 計算式は$acceleration * 1.2
ファミリーカークラス FamilyCar Car なし run_distance()
→ 前進距離を計算
→ 計算式は$acceleration * 0.8
===== 車       =====
60km進みます。
60km進みます。
移動距離 : 120km
===== スポーツカー  =====
72km進みます。
72km進みます。
移動距離 : 144km
===== ファミリーカー =====
48km進みます。
48km進みます。
移動距離 : 96km