採点されません。匿名です。 間違えることは学習の一部です。読むだけでもかまいません。

final クラス / final メソッド

テクノロジ系 / class-advanced (継承 / オーバーライド / abstract / interface / static / const / final)

final クラス / final メソッド

Lesson 9 / Chapter 8

継承されると困るクラスがある

<?php
class Logger {
    public function log(string $msg) {
        echo "[LOG] $msg\n";
    }
}

class BadLogger extends Logger {
    public function log(string $msg) {
        // パスワードを画面に出してしまう実装に変えられてしまった!
        echo "[LEAK] $msg\n";
    }
}
  • 継承できると、第三者にどんな振る舞いに変えられるか分からない
  • セキュリティ上、改造を禁じたいときがある

final class で継承を禁止

<?php
final class Logger {
    public function log(string $msg) {
        echo "[LOG] $msg\n";
    }
}

class BadLogger extends Logger {   // ❌ Fatal error
}
  • class の前に final を付ける
  • このクラスを継承しようとした瞬間にエラー
  • 「これは設計が完成しているので、改造禁止」という意思表示

final メソッドはオーバーライドを禁止

<?php
class Logger {
    final public function log(string $msg) {
        echo "[LOG] $msg\n";
    }
}

class TimedLogger extends Logger {
    public function log(string $msg) {   // ❌ Fatal error
        echo "...\n";
    }
}
  • クラス自体は継承できる
  • でも 特定のメソッドだけ はオーバーライドさせない
  • 「ここの動きは絶対変えるな」という保護

使い分け

やりたいこと
final classクラスごと拡張不可にする
final functionクラスは継承可、でもこのメソッドだけ変えさせない

「外部に公開する設計済みクラス」「金額計算など壊されたら困る処理」に有効。

このチャプターでできるようになること

final class で継承を禁止できる

final function でオーバーライドを禁止できる

✅ 「拡張されたら困る箇所」に意図を明示できる

→ ドリルへ

考えてみよう

既定では正解・不正解の判定はしません。自分のペースで「答えを見る」を。採点してほしい場合だけ「採点してほしい」を押してください。

ドリル 01 — final class でインスタンスを作る

問題

Logger クラスを final を付けて定義してください。

  • メソッド log(string $msg)"[LOG] {msg}" を 1 行出力する

Logger のインスタンスを作って、log("started") を呼んでください。

期待される出力:

[LOG] started

採点

php scripts/grade.php topics/class-advanced/ch08-final/drill/01-final-class/

メモ

  • final class を継承しようとすると Fatal error になります
  • このドリルでは「final を付けても インスタンス化と通常メソッド呼び出しは普通にできる」ことを確認します

ヒント

  • final class Logger { ... }
  • $l = new Logger();
  • $l->log("started");