第10章 クラス

クラスとオブジェクト

PHPでは、クラスを定義し、そのクラスからオブジェクト(インスタンス)を生成することでオブジェクト指向プログラミングを行います。

以下に簡単な例を示します。

// クラスの定義
class Car {
    // 何も定義しないクラスも可能
}

// オブジェクトの生成
$car = new Car();


プロパティとメソッド

クラスの中で定義される変数をプロパティ(またはフィールド)、関数をメソッドと呼びます。

class Car {
    // プロパティ
    public $color;

    // メソッド
    public function setColor($color) {
        $this->color = $color;
    }
}

$car = new Car();
$car->setColor("赤");
echo $car->color;  // "赤" が出力される


コンストラクタとデストラクタ

コンストラクタはオブジェクト生成時に自動的に呼び出される特殊なメソッドで、デストラクタはオブジェクトが破棄される時に自動的に呼び出されます。

class Car {
    public $color;

    // コンストラクタ
    public function __construct($color) {
        $this->color = $color;
        echo "車が生成されました。\n";
    }

    // デストラクタ
    public function __destruct() {
        echo "車が破棄されました。\n";
    }
}

$car = new Car("赤");  // "車が生成されました。" が出力される
unset($car);  // "車が破棄されました。" が出力される


アクセス修飾子

アクセス修飾子は、クラスの外からのプロパティやメソッドのアクセスを制限します。publicprotectedprivateの3つがあります。

class Car {
    public $color;  // どこからでもアクセス可能
    protected $engine;  // 自クラスおよび派生クラスからアクセス可能
    private $oil;  // 自クラスからのみアクセス可能
}


継承

継承を利用すると、既存のクラスのプロパティやメソッドを引き継ぐ新たなクラスを定義できます。

class Car {
    public $color;

    public function setColor($color) {
        $this->color = $color;
    }
}

// Carクラスを継承したSportsCarクラスを定義
class SportsCar extends Car {
    public $maxSpeed;
}

$sportsCar = new SportsCar();
$sportsCar->setColor("赤");
$sportsCar->maxSpeed = 200;


オーバーライドとポリモーフィズム

継承先のクラスで元のクラスのメソッドを再定義することをオーバーライドといいます。これにより、同じメソッド名で異なる振る舞いを実現できます(ポリモーフィズム)。

class Car {
    public function run() {
        echo "車が走ります。\n";
    }
}

class SportsCar extends Car {
    public function run() {
        echo "スポーツカーが高速で走ります。\n";
    }
}

$car = new Car();
$car->run();  // "車が走ります。" を出力

$sportsCar = new SportsCar();
$sportsCar->run();  // "スポーツカーが高速で走ります。" を出力


インターフェイス

インターフェイスは、どのようなメソッドを持つべきかを定義したもので、クラスはインターフェイスを実装してそのメソッドを具体的に定義します。

interface Vehicle {
    public function run();
}

class Car implements Vehicle {
    public function run() {
        echo "車が走ります。\n";
    }
}


抽象クラス

抽象クラスは、一部または全てのメソッドが具体的な実装を持たないクラスです。抽象クラスを継承するクラスでは、抽象メソッドの具体的な実装を提供する必要があります。

abstract class Vehicle {
    abstract public function run();
}

class Car extends Vehicle {
    public function run() {
        echo "車が走ります。\n";
    }
}


例外処理

PHPのオブジェクト指向プログラミングでは、エラー発生時に例外(Exception)を投げ、それをキャッチして処理することが一般的です。

class Car {
    public function startEngine() {
        throw new Exception("エンジンが故障しています。");
    }
}

$car = new Car();

try {
    $car->startEngine();
} catch (Exception $e) {
    echo $e->getMessage();  // "エンジンが故障しています。" が出力される
}


練習問題1.

以下の要件に従い、クラスを作成してください。

クラス名は「Dog」です。

「Dog」クラスには「name」、「age」、「breed」のプロパティがあります。

各プロパティにはgetterとsetterメソッドがあります。


練習問題2.

次のクラス「Rectangle」を作成してください。

class Rectangle {
    // ここにコードを書いてください
}

このクラスは、長方形の高さと幅をプロパティとして持ち、以下の2つのメソッドを持つ必要があります。

getArea():長方形の面積を返します。

getPerimeter():長方形の周囲の長さを返します。


練習問題3.

次に示す「Vehicle」クラスがあります。このクラスを継承した「Car」クラスと「Bicycle」クラスを作成してください。

class Vehicle {
    protected $speed;

    public function setSpeed($speed) {
        $this->speed = $speed;
    }

    public function getSpeed() {
        return $this->speed;
    }
}

「Car」クラスは追加で$fuelプロパティを持ち、「Bicycle」クラスは追加で$gearプロパティを持つとします。それぞれのプロパティに対して、適切なgetterとsetterメソッドを追加してください。