基礎

PHPのクラス継承(extends)|親クラスの機能を引き継ぐ方法

PHPのクラス継承は、既存のクラス(親クラス)の機能を引き継いで新しいクラス(子クラス)を作る仕組みです。extends キーワードを使って親クラスを指定すると、親のプロパティやメソッドをそのまま使えます。

継承を使うことで、共通の機能を親クラスにまとめ、差分だけを子クラスに記述できるため、コードの重複を大幅に減らせます。オブジェクト指向の重要な柱のひとつです。

基本的な使い方

PHP
<?php
class Animal {
    public function __construct(
        protected string $name,
        protected int $age
    ) {}

    public function introduce(): string {
        return "{$this->name}({$this->age}歳)";
    }
}

class Dog extends Animal {
    public function bark(): string {
        return "{$this->name}がワンワンと吠えた!";
    }
}

class Cat extends Animal {
    public function meow(): string {
        return "{$this->name}がニャーと鳴いた!";
    }
}

$dog = new Dog("ポチ", 3);
$cat = new Cat("タマ", 5);

echo $dog->introduce() . "\n";
echo $dog->bark() . "\n";
echo $cat->introduce() . "\n";
echo $cat->meow() . "\n";
実行結果
ポチ(3歳)
ポチがワンワンと吠えた!
タマ(5歳)
タマがニャーと鳴いた!

DogCatAnimal を継承しているため、introduce() メソッドをそのまま使えます。さらに、それぞれ独自のメソッドを追加しています。

メソッドのオーバーライド

子クラスで親クラスと同名のメソッドを定義すると、親の処理を上書き(オーバーライド)できます。

PHP
<?php
class Shape {
    public function area(): float {
        return 0.0;
    }

    public function describe(): string {
        return "面積: " . $this->area();
    }
}

class Circle extends Shape {
    public function __construct(private float $radius) {}

    // 親のarea()をオーバーライド
    public function area(): float {
        return M_PI * $this->radius ** 2;
    }
}

class Rectangle extends Shape {
    public function __construct(
        private float $width,
        private float $height
    ) {}

    public function area(): float {
        return $this->width * $this->height;
    }
}

$circle = new Circle(5);
$rect = new Rectangle(4, 6);

echo "円 - " . $circle->describe() . "\n";
echo "長方形 - " . $rect->describe() . "\n";
実行結果
円 - 面積: 78.539816339745
長方形 - 面積: 24

parentキーワード

parent:: を使うと、オーバーライドした親クラスのメソッドを呼び出せます。

PHP
<?php
class BaseLogger {
    public function log(string $message): void {
        echo "[" . date("Y-m-d H:i:s") . "] " . $message . "\n";
    }
}

class FileLogger extends BaseLogger {
    public function log(string $message): void {
        // 親のlogも呼び出す(画面表示)
        parent::log($message);
        // 追加の処理(ファイル出力の代わりにメッセージ表示)
        echo "  → ファイルにも記録しました\n";
    }
}

$logger = new FileLogger();
$logger->log("アプリケーション開始");
$logger->log("処理完了");
実行結果
[2026-02-19 10:00:00] アプリケーション開始
  → ファイルにも記録しました
[2026-02-19 10:00:00] 処理完了
  → ファイルにも記録しました

実用的な例

PHP
<?php
class BaseController {
    protected array $data = [];

    protected function setTitle(string $title): void {
        $this->data["title"] = $title;
    }

    public function render(): void {
        foreach ($this->data as $key => $value) {
            echo "{$key}: {$value}\n";
        }
    }
}

class HomeController extends BaseController {
    public function index(): void {
        $this->setTitle("ホーム");
        $this->data["content"] = "ようこそ!";
        $this->render();
    }
}

class AboutController extends BaseController {
    public function index(): void {
        $this->setTitle("会社概要");
        $this->data["content"] = "私たちについて";
        $this->data["established"] = "2020年";
        $this->render();
    }
}

echo "=== Home ===\n";
(new HomeController())->index();
echo "\n=== About ===\n";
(new AboutController())->index();
実行結果
=== Home ===
title: ホーム
content: ようこそ!

=== About ===
title: 会社概要
content: 私たちについて
established: 2020年
ポイント

PHPでは単一継承のみサポートされます(1つのクラスからしか継承できない)。複数のクラスの機能を取り込みたい場合は、インターフェースやトレイトを使います。継承の階層が深くなりすぎると複雑になるため、2〜3階層に抑えるのが目安です。

注意

「継承よりコンポジション(委譲)を優先する」はオブジェクト指向の重要な原則です。「AはBの一種である(is-a関係)」が成り立つ場合のみ継承を使い、「AはBを持っている(has-a関係)」の場合はプロパティとして持つ方が柔軟な設計になります。

まとめ

  • extends で親クラスのプロパティとメソッドを引き継げる
  • 子クラスで同名メソッドを定義するとオーバーライド(上書き)できる
  • parent:: で親クラスのメソッドを呼び出せる
  • PHPは単一継承のみ。複数継承が必要ならトレイトやインターフェースを使う
  • is-a関係のときのみ継承を使い、has-a関係ではコンポジションを優先する