# ch06 — コンストラクタで初期化する

Source: https://php-school.pages.dev/topics/class/ch06-constructor/
Site: AIと学ぶPHPの学校 (https://php-school.pages.dev)
Lesson: クラスの基本
Level: L3

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

## 本文

# ch06 — コンストラクタで初期化する

## 概要

コンストラクタ (`__construct`) は **`new` の瞬間に自動的に呼ばれる特別なメソッド** で、インスタンスが生まれると同時にプロパティを初期化するために使う。これまでは `new User(); $u->name = "太郎"; $u->age = 20;` のように 3 行に分けて書いてきたが、`__construct(string $name, int $age)` を定義しておけば `new User("太郎", 20)` の **1 行で生成と初期化が完了** する。代入忘れも防げて、設計図側に「このクラスはこの値が必ず必要」という意図を残せる。

書き方は `public function __construct(...) { ... }` で、メソッド名は **アンダースコア 2 つ + construct** と決まっている。中で `$this->name = $name;` のように引数をプロパティに代入していくのが定番パターン。`new クラス名(引数, ...)` のときに `()` の中に書いた値が、そのままコンストラクタの引数として渡る仕組みになっている。引数名とプロパティ名を同じにしても `$this->` が付くかどうかで判別されるので混ざらない。

PHP 8 には **コンストラクタプロモーション** という短縮記法もあり、`public function __construct(public string $name, public int $age) { }` と書くだけでプロパティ宣言と代入を一気に済ませられる。本章ではまず標準形のコンストラクタを書けるところを目標にして、短縮形は補足として頭の片隅に置いておく。

## 学習目標

- `__construct(...)` という特別なメソッドが `new` の瞬間に呼ばれると言える
- コンストラクタ引数でプロパティを初期化できる
- `new クラス名(引数, ...)` で 1 行で生成・初期化できる

## 所要時間

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

## ドリル

| no | 内容 |
|---|---|
| 01 | `__construct(string $name, int $age)` で初期化する |

## 採点

```bash
php scripts/grade.php topics/class/ch06-constructor/drill/01-init/
```

## 関連チャプター

- [`ch05-this`](../ch05-this/) — `$this->prop` でプロパティ参照 (前提)
- [`ch04-methods`](../ch04-methods/) — 通常メソッドの定義
- [`ch07-visibility`](../ch07-visibility/) — `private` プロパティとコンストラクタの組み合わせ
- [`../../09-class-advanced/ch03-parent-call`](../../09-class-advanced/ch03-parent-call/) — 親のコンストラクタを呼ぶ (応用)

## スライド

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

<!--
LLM_CONTEXT:
  Lesson 8 / Chapter 6
  目的: __construct を定義し、new の瞬間にプロパティを初期化できるようにする
  扱わない: 修飾子 (ch07) / 継承・static (L9)
  読み上げ時間目安: 3 分半〜4 分
-->

# コンストラクタで初期化する

Lesson 8 / Chapter 6

---

## 「new してから 1 つずつ代入」は面倒

```php
<?php
$u = new User();
$u->name = "太郎";
$u->age  = 20;
```

- インスタンスを使うたびに 3 行も書く必要がある
- 代入し忘れたまま使うとバグの原因になる
- **生成と初期化** をまとめて 1 行で済ませたい

---

## `__construct` は `new` の瞬間に呼ばれる

```php
<?php
class User {
    public string $name;
    public int $age;

    public function __construct(string $name, int $age) {
        $this->name = $name;
        $this->age  = $age;
    }
}

$u = new User("太郎", 20);

echo $u->name . "\n";  // 太郎
echo $u->age  . "\n";  // 20
```

- メソッド名は **必ず** `__construct` (アンダースコア 2 つ + construct)
- `new User("太郎", 20)` のように **`new` の `()` に引数を書く**
- 中で `$this->prop = ...` でプロパティを初期化する

---

## 引数名とプロパティ名が同じ場合

```php
public function __construct(string $name, int $age) {
    $this->name = $name;   // 左は this の name、右は引数の $name
    $this->age  = $age;
}
```

- 左辺の `$this->name` は **プロパティ**
- 右辺の `$name` は **引数**
- 同じ名前にしても混ざらない (`$this->` が付いているかどうかで判別される)

---

## 1 行で生成と初期化を済ませられる

```php
<?php
$a = new User("太郎", 20);
$b = new User("花子", 25);

echo $a->name . " (" . $a->age . ")\n";
echo $b->name . " (" . $b->age . ")\n";
```

実行結果:

```
太郎 (20)
花子 (25)
```

- インスタンスを作るたびに「3 行」が「1 行」になる
- どのプロパティを必ず初期化するかが **設計図に書かれる** ので、初期化忘れも防げる

---

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

✅ `__construct` という特別なメソッドが `new` の瞬間に呼ばれると言える
✅ コンストラクタ引数でプロパティを初期化できる
✅ `$this->prop = $引数;` のパターンを書ける
✅ `new クラス名(引数, ...)` で 1 行で生成・初期化できる

→ ドリルへ
