導入
第5章の「買い物カゴ」の例では、1件の商品を連想配列 ["name" => ..., "price" => ...] で表しました。これでもプログラムは書けますが、「この商品を表示用の文字列にする」処理をどこに置くかが定まらず、似た処理があちこちに散らばりがちです。クラスを使うと、データ(プロパティ)とそれを扱う処理(メソッド)を1つの型としてまとめられます。
説明
class でクラスを定義します。データを入れる場所をプロパティ、クラスに属する関数をメソッドと呼びます。new クラス名(...) でインスタンス(実体)を作ります。
<?php
class Product {
public string $name;
public int $price;
public function __construct(string $name, int $price) {
$this->name = $name;
$this->price = $price;
}
public function label(): string {
return "{$this->name}: {$this->price}円";
}
}
$p = new Product("ノート", 300);
echo $p->label(), "\n"; // ノート: 300円
__construct() はコンストラクタと呼ばれる特別なメソッドで、new したときに自動で呼ばれます。ここで受け取った引数をプロパティに保存するのが定番の書き方です。$this は「今このメソッドが呼ばれているインスタンス自身」を指します。プロパティやメソッドには $this->名前 でアクセスします。
プロパティやメソッドの前には可視性を書きます。public はクラスの外からも自由にアクセスできる、private はクラスの内側(そのクラス自身)からしかアクセスできない、protected はそのクラスと継承先のクラスからアクセスできる、という意味です。
<?php
class BankAccount {
private int $balance = 0; // 外からは直接触れない
public function deposit(int $amount): void {
$this->balance += $amount;
}
public function balance(): int {
return $this->balance;
}
}
$acc = new BankAccount();
$acc->deposit(1000);
$acc->deposit(500);
echo $acc->balance(), "\n"; // 1500
// $acc->balance = 999999; ← private なのでこれはエラーになる
balance を private にすることで、外から勝手に書き換えられず、必ず deposit() を通してしか増やせないようにしています。こうして「安全に使える窓口」だけを public で公開する考え方をカプセル化と呼びます。
やってみよう
Product に $stock(在庫数)プロパティを追加し、label() の表示に含めてみましょう。BankAccount に withdraw($amount)(引き出し)メソッドを足して、残高が足りないときは引き出せないようにしてみるのもよい練習です。
演習
クラス Item を作ってください。プロパティは public string $name と public int $price、コンストラクタで両方を受け取って保存します。さらにメソッド describe(): string を作り、"ノート: 300円" のように "{名前}: {価格}円" の形で返してください。$item = new Item("ノート", 300); を作り、describe() の結果を表示しましょう。
ヒント1を見る
class Item { public string $name; public int $price; public function __construct(string $name, int $price) { $this->name = $name; $this->price = $price; } }
ヒント2を見る
public function describe(): string { return "{$this->name}: {$this->price}円"; } を追加し、echo $item->describe(), "\n"; で呼び出します。