ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
基本
class Animal
{
public function __construct(protected string $name) {}
public function speak(): string
{
return "{$this->name} が鳴いた";
}
public function name(): string
{
return $this->name;
}
}
class Dog extends Animal
{
public function speak(): string // 上書き(オーバーライド)
{
return "{$this->name}: ワン";
}
public function fetch(): string // 子だけの機能
{
return "取ってきた";
}
}
$d = new Dog('ポチ');
echo $d->speak(); // ポチ: ワン
echo $d->name(); // ポチ 親のメソッドも使える
echo $d->fetch(); // 取ってきた
var_dump($d instanceof Dog); // true
var_dump($d instanceof Animal); // true 親としても扱える
親の実装を呼ぶ
class Cat extends Animal
{
public function __construct(string $name, private bool $indoor = true)
{
parent::__construct($name); // ← 忘れると $name が未初期化になる
}
public function speak(): string
{
return parent::speak() . '(ニャー)'; // 親の結果に足す
}
}
echo (new Cat('タマ'))->speak(); // タマ が鳴いた(ニャー)
子クラスで __construct を定義しなければ親のものがそのまま使われます。定義した時点で親の初期化は行われなくなるので、parent::__construct() の呼び忘れに注意してください。
可視性(private / protected / public)
class Base
{
public string $a = 'public'; // どこからでも
protected string $b = 'protected'; // 自分と子クラスから
private string $c = 'private'; // 自分のクラスの中だけ
public function show(): void
{
echo $this->a, $this->b, $this->c; // 全部見える
}
}
class Child extends Base
{
public function test(): void
{
echo $this->a; // OK
echo $this->b; // OK
echo $this->c; // Warning: Undefined property Child::$c
}
}
$o = new Child();
echo $o->a; // OK
// echo $o->b; // Error: Cannot access protected property
| クラス内 | 子クラス | 外部 | |
|---|---|---|---|
public | ○ | ○ | ○ |
protected | ○ | ○ | × |
private | ○ | × | × |
継承される前提のクラスでは、子に触ってほしいものを protected、内部実装を private にします。迷ったら狭いほうから始めて、必要になったら広げてください。
final で継承を止める
final class Money { } // このクラスは継承できない
// class Yen extends Money {} // Fatal error: Class Yen cannot extend final class Money
class Service
{
final public function run(): void // このメソッドは上書きできない
{
$this->before();
$this->handle();
$this->after();
}
protected function handle(): void {} // ここだけ子に差し替えさせる
private function before(): void {}
private function after(): void {}
}
処理の流れは固定して一部だけ差し替えさせたいときに final が役立ちます(テンプレートメソッドパターン)。
インターフェース
interface Speaker
{
public function speak(): string; // 実装は書かない
}
interface Walker
{
public function walk(): string;
}
class Robot implements Speaker, Walker // 複数実装できる
{
public function speak(): string { return 'ピー'; }
public function walk(): string { return 'ガシャン'; }
}
function announce(Speaker $s): void // 型として使える
{
echo $s->speak();
}
announce(new Robot());
announce(new Dog('ポチ')); // Dog も implements Speaker していれば渡せる
親クラスは 1 つしか持てませんが、インターフェースはいくつでも実装できます。「これができる」という役割を型で表したいときはインターフェースを使います。
トレイト(実装の使い回し)
trait Timestampable
{
private ?string $createdAt = null;
public function touch(): void
{
$this->createdAt = date('Y-m-d H:i:s');
}
}
trait Loggable
{
public function log(string $msg): void
{
error_log(static::class . ': ' . $msg);
}
}
class Article
{
use Timestampable, Loggable; // 複数まとめて取り込める
}
$a = new Article();
$a->touch();
$a->log('作成');
トレイトは継承関係とは無関係にメソッドを配る仕組みです。同じ名前のメソッドが衝突したときは insteadof と as で解決します。
trait A { public function hello(): string { return 'A'; } }
trait B { public function hello(): string { return 'B'; } }
class C
{
use A, B {
A::hello insteadof B; // A のほうを採用
B::hello as helloB; // B のほうは別名で使う
}
}
echo (new C())->hello(); // A
echo (new C())->helloB(); // B
3 つの使い分け
| 目的 | 数 | 実装を持てるか | |
|---|---|---|---|
extends(継承) | 「〜は〜の一種」を表す | 1 つだけ | 持てる |
implements(インターフェース) | 「〜ができる」を型で表す | いくつでも | 持てない(定数と宣言のみ) |
use(トレイト) | 実装を配る | いくつでも | 持てる(型としては使えない) |
継承より委譲を選ぶ場面
// 良くない継承: 「Stack は ArrayObject の一種」ではない
class Stack extends ArrayObject
{
public function push($v): void { $this[] = $v; }
}
$s = new Stack();
$s->push(1);
$s->asort(); // 親の余計な機能まで公開されてしまう
// 委譲: 必要な操作だけを見せる
class Stack
{
private array $items = [];
public function push(mixed $v): void { $this->items[] = $v; }
public function pop(): mixed { return array_pop($this->items); }
public function count(): int { return count($this->items); }
}
継承すると親の public メソッドがすべて子でも使えるようになります。「便利だから継承する」と、意図しない使われ方を許すことになります。「子は親としても正しく振る舞えるか」を基準に判断してください(ポリモーフィズム(多様性)の具体例)。
関連
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページ
子ページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- 【django】ログイン 認証機能 2026-09-08 03:22:09
- MySQL ERROR 1063 Incorrect column specifier for column|原因と直し方 2026-09-08 03:11:09
- 【PHPエラー】Object of class stdClass could not be converted to string 2026-09-07 07:46:04
- Julia Genie ローカル開発サーバ起動完全ガイド 2026-09-07 07:46:04
- Wi-Fi とは|規格と世代(Wi-Fi 4〜7)・周波数帯・CSMA/CA・WPA3 NEW 2026-09-07 07:45:13
- set コマンドでシェルオプションと位置パラメータを操作 | bash 2026-09-07 07:45:13
- JPEG(.jpg/.jpeg)画像形式の完全ガイド — 仕様・マジックナンバー・他形式との比較・EXIF 2026-09-07 07:45:13
- UE5 Get Overlapping Actorsで特定クラスだけ処理|Class Filter・Cast To 2026-09-07 07:45:13
- Linuxで特定拡張子のファイルを再帰削除|find -deleteの安全手順 2026-09-07 07:45:13
- Django CBVでテンプレートに値を渡す|get_context_data・extra_context 2026-09-07 07:45:13
- Linuxで複数ファイルの文字列を一括置換|find・sed・xargsの安全手順 2026-09-07 07:45:13
- Laravelルートグループ|prefix・middleware・nameで一括管理 2026-09-07 07:45:13
- Linux whichコマンドの使い方|絶対パス取得とtype・command -vの違い 2026-09-07 07:45:13
- Linux catコマンドの使い方|行番号表示・複数ファイル連結 2026-09-07 07:45:13
- unable to execute 'gcc': No such file or directory 2026-09-07 07:45:13
コメントを削除してもよろしいでしょうか?