# ch03 — 親メソッドを呼ぶ (parent::)

Source: https://php-school.pages.dev/topics/class-advanced/ch03-parent-call/
Site: AIと学ぶPHPの学校 (https://php-school.pages.dev)
Lesson: クラスの応用
Level: L3

Reference (official): https://www.php.net/manual/ja/language.oop5.inheritance.php

## 本文

# ch03 — 親メソッドを呼ぶ (parent::)

## 概要

オーバーライドした子メソッドの中から **親の処理も走らせたい** ときがある。例えば子の `greet()` で「親の挨拶を出した後に、子独自のメッセージを追加する」ような合成だ。このために PHP には `parent::method()` という記法があり、子のメソッド内から親クラスのメソッドを明示的に呼び出せる。`parent::greet();` を実行すると、いま自分が動いているクラスの **親の同名メソッド** が呼ばれる。

`parent::` は **「親を捨てずに拡張する」** ためのキーで、特に **コンストラクタの連鎖** で重要になる。親クラスが `__construct(string $name)` で何かを初期化しているなら、子クラスのコンストラクタの最初の行で `parent::__construct($name);` を呼んでおかないと、親側の初期化が走らずプロパティが未初期化のまま残ってしまう。「子コンストラクタの先頭で `parent::__construct()` を呼ぶ」は実務で頻出する慣習になる。

`$this->method()` と `parent::method()` の違いを区別しておく。`$this->method()` はオーバーライドを考慮して **実体のクラスのメソッド** を呼ぶ (子で上書きされていれば子が走る)。`parent::method()` は明示的に **親のメソッド** を呼ぶ。同じ名前で書ける場合でも、意図がまったく違うので使い分けに注意する。

## 学習目標

- `parent::method()` で親クラスのメソッドを明示的に呼べる
- オーバーライドした上で親の処理も走らせる「合成」ができる
- 親の処理を捨てずに拡張する書き方を理解する

## 所要時間

スライド 4 分 + ドリル 1 問 = **10 分**

## ドリル

| no | 内容 |
|---|---|
| 01 | 子クラスの `greet()` で `parent::greet()` を呼んで合成する |

## 採点

```bash
php scripts/grade.php topics/class-advanced/ch03-parent-call/drill/01-parent-call/
```

## 関連チャプター

- [`ch02-override`](../ch02-override/) — オーバーライド (前提)
- [`ch01-inheritance`](../ch01-inheritance/) — 継承
- [`../../08-class/ch06-constructor`](../../08-class/ch06-constructor/) — コンストラクタの基本 (合成の典型例)

## スライド

---
marp: true
theme: dojo
paginate: true
size: 16:9
---

<!--
LLM_CONTEXT:
  Lesson 9 / Chapter 3
  目的: parent::method() で親クラスのメソッドを呼び、オーバーライドと親処理を併用する
  扱わない: abstract (ch04) / interface (ch05) / static (ch06) / 親コンストラクタ呼び出しは ch08 課題範囲外
  読み上げ時間目安: 3 分半〜4 分
-->

# 親メソッドを呼ぶ (parent::)

Lesson 9 / Chapter 3

---

## オーバーライドすると、親の処理は消える

```php
<?php
class Greeter {
    public function greet() {
        echo "こんにちは\n";
    }
}

class FormalGreeter extends Greeter {
    public function greet() {
        echo "本日はお世話になります\n";
    }
}
```

- 子で `greet()` を書くと、親の「こんにちは」は出ない
- でも「親の挨拶 + 自分の追加」をしたいときがある

---

## `parent::method()` で親を呼べる

```php
<?php
class FormalGreeter extends Greeter {
    public function greet() {
        parent::greet();   // 親の greet() を呼ぶ
        echo "本日はお世話になります\n";
    }
}
```

- `parent::` は「親クラスの」という意味
- `parent::greet()` で **親で定義された** `greet()` を実行できる

---

## 子のインスタンスから呼んでみる

```php
<?php
$g = new FormalGreeter();
$g->greet();
```

実行結果:

```
こんにちは
本日はお世話になります
```

- 親の処理が先、その後に子の追加処理
- 順番は自由 (子の処理 → 親、でも良い)

---

## 「親の処理を残しつつ拡張」する典型パターン

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

class TimedLogger extends Logger {
    public function log(string $msg) {
        echo "[2026-05-18] ";
        parent::log($msg);   // 親の処理を再利用
    }
}
```

- 親の `log` を書き直さずに済む
- 親が変わっても、自動的に追従する

---

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

✅ `parent::method()` で親メソッドを呼べる
✅ オーバーライド + 親処理の合成ができる
✅ 親の処理を捨てずに拡張する書き方ができる

→ ドリルへ
