Menu
Coddy logo textTech

Private と Protected プロパティ

CoddyのPHPジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 18/91。

これまで、どこからでもアクセスできる public プロパティを使用してきました。しかし、データを保護するためにアクセスを制限する必要がある場合があります。PHPは、さらに2つの可視性修飾子、privateprotected を提供しています。

private プロパティは、それを定義したクラス内からのみアクセスできます:

<?php
class BankAccount {
    private $balance = 0;
    
    public function deposit($amount) {
        $this->balance += $amount;
    }
    
    public function getBalance() {
        return $this->balance;
    }
}

$account = new BankAccount();
$account->deposit(100);
echo $account->getBalance();

出力:

100

クラスの外部から直接 $account->balance にアクセスしようとすると、エラーが発生します。これにより、deposit メソッドを経由せずに残高が変更されるのを防ぎます。

protected プロパティも同様に動作しますが、親クラスを継承する子クラスからもアクセスできるという点が異なります:

<?php
class User {
    protected $email;
    
    public function __construct($email) {
        $this->email = $email;
    }
}

class Admin extends User {
    public function showEmail() {
        return $this->email;
    }
}

$admin = new Admin("admin@example.com");
echo $admin->showEmail();

出力:

admin@example.com

重要ポイント: 定義しているクラスのみがプロパティにアクセスする必要がある場合は、privateを使用します。子クラスもアクセスする必要がある場合は、protectedを使用します。どちらも外部からの直接アクセスを防ぎ、オブジェクトの内部状態を安全に保ちます。

challenge icon

チャレンジ

簡単

privateプロパティとprotectedプロパティを使用して機密データを保護する方法を示す、安全な従業員管理システムを構築しましょう。

適切なアクセス制御を備えた従業員情報を管理するために、連携して動作する3つのファイルを作成します。

  • Employee.php — すべての従業員のベースとなる Employee クラスを定義します。このクラスには、protected $name プロパティ(子クラスがアクセスできるようにするため)と private $salary プロパティ(このクラスのみが給与を直接変更できるようにするため)を持たせる必要があります。コンストラクタは名前と給与を受け取り、両方のプロパティを設定します。名前を返すパブリックな getName() メソッド、給与を返すパブリックな getSalary() メソッド、および指定された金額だけ給与を増やすパブリックな giveRaise($amount) メソッドを追加します。
  • Manager.phpEmployee を継承する Manager クラスを定義します。ファイルの先頭で Employee ファイルをインクルードしてください。プライベートな $department プロパティを追加します。コンストラクタは名前、給与、部署を受け取る必要があります。名前と給与については親のコンストラクタを呼び出し、その後に部署を設定します。protectedな $name プロパティに直接アクセスして、"[name] manages [department]" を返す getDetails() メソッドを作成します。また、部署を返す getDepartment() メソッドも追加します。
  • main.php — 両方のクラスファイルをインクルードします。名前が "Sarah"、給与が 75000、部署が "Engineering"Manager を作成します。getDetails() を使用してマネージャーの詳細を出力します。次に、マネージャーに 5000 の昇給を与え、getSalary() を使用して新しい給与を出力します。各出力は個別の行に表示されるようにしてください。

Manager クラスが protected な $name プロパティには直接アクセスできる一方で、private な給与にアクセスするには getSalary() メソッドを使用しなければならない点に注目してください。これは、protected と private の可視性の重要な違いを示しています。protected は子クラスからのアクセスを許可しますが、private はデータを完全に隠蔽します。

チートシート

PHPは、クラスのプロパティに対して3つの可視性修飾子を提供しています:

  • public — どこからでもアクセス可能
  • private — 定義されたクラス内からのみアクセス可能
  • protected — 定義されたクラスおよび子クラス内からアクセス可能

Privateプロパティ:

class BankAccount {
    private $balance = 0;
    
    public function deposit($amount) {
        $this->balance += $amount;
    }
    
    public function getBalance() {
        return $this->balance;
    }
}

Privateプロパティは、クラスの外から直接アクセスすることはできません。これらを操作するには、publicメソッドを使用します。

Protectedプロパティ:

class User {
    protected $email;
    
    public function __construct($email) {
        $this->email = $email;
    }
}

class Admin extends User {
    public function showEmail() {
        return $this->email; // Child class can access protected property
    }
}

Protectedプロパティは、親クラスを継承した子クラスからアクセスすることができます。

いつ使用するか:

  • 定義されたクラスのみがプロパティにアクセスする必要がある場合は、privateを使用します
  • 子クラスもアクセスする必要がある場合は、protectedを使用します
  • どちらも外部からの直接アクセスを防ぎ、オブジェクトの内部状態を保護します

自分で試してみよう

<?php
require_once 'Employee.php';
require_once 'Manager.php';

// TODO: 名前 "Sarah"、給与 75000、部署 "Engineering" でマネージャーを作成します

// TODO: getDetails() を使用してマネージャーの詳細を表示します

// TODO: マネージャーに 5000 の昇給を与えます

// TODO: getSalary() を使用して新しい給与を表示します
?>
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン