Public, Protected, Private
CoddyのPHPジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 38/91。
カプセル化の章へようこそ!カプセル化とは、クラスの内部データへのアクセスを制御することです。PHPは、プロパティやメソッドがどこからアクセスできるかを決定する3つのアクセス修飾子を提供しています:public、protected、およびprivate。
各修飾子の仕組みは次のとおりです:
<?php
class BankAccount {
public $accountHolder; // どこからでもアクセス可能
protected $accountNumber; // このクラスおよび子クラスからアクセス可能
private $balance; // このクラス内からのみアクセス可能
public function __construct($holder, $number, $balance) {
$this->accountHolder = $holder;
$this->accountNumber = $number;
$this->balance = $balance;
}
public function getBalance() {
return $this->balance;
}
}
$account = new BankAccount("John", "12345", 1000);
echo $account->accountHolder . "\n"; // 動作する - public
echo $account->getBalance(); // 動作する - publicメソッド
出力:
John
1000$account->balance に直接アクセスしようとすると、それは private であるためエラーが発生します。クラス階層の外側からの $account->accountNumber に対しても同様です。この保護により、機密データは制御されたメソッドを通じてのみ変更できることが保証されます。
| 修飾子 | 同一クラス | 子クラス | 外部 |
|---|---|---|---|
public | Yes | Yes | Yes |
protected | Yes | Yes | No |
private | Yes | No | No |
重要なポイント: 直接アクセスすべきではない内部データには private を使用し、子クラスが必要とするデータには protected を、そして安全な外部アクセスにのみ public を使用してください。
チャレンジ
簡単アクセス修飾子がどのように機密データを保護するかを実証する、安全な従業員管理システムを構築しましょう。クラス内、子クラス内、または外部からといった、コードが実行されている場所に応じて、異なるレベルの情報にアクセスできるクラス階層を作成します。
コードは3つのファイルに分けて構成します:
Employee.php— 適切な可視性レベルで従業員データを管理するEmployeeクラスを作成します。クラスには以下を含める必要があります:- 従業員名のための
publicプロパティ$name(誰でも見ることができます) - 内部IDのための
protectedプロパティ$employeeId(子クラスで必要になります) - 機密性の高い給与情報のための
privateプロパティ$salary(このクラスのみが直接アクセスできます)
getSalary()を追加してください。これが保護されたデータにアクセスするための制御された方法です。また、"[name] works here"を返すパブリックメソッドgetPublicInfo()も追加してください。- 従業員名のための
Manager.php—Employeeを継承するManagerクラスを作成します。Employee ファイルをインクルードしてください。コンストラクタは、名前、従業員ID、給与、および部署名を受け取る必要があります。最初の3つの値で親のコンストラクタを呼び出し、次に部署名をプライベートプロパティに保存します。"Manager [name] (ID: [employeeId]) leads [department]"を返すパブリックメソッドgetTeamInfo()を追加してください。子クラスが保護された$employeeIdにはアクセスできる一方で、プライベートな給与にアクセスするにはgetSalary()が必要であることに注目してください。main.php— Manager ファイルをインクルードしてください。名前、従業員ID、給与(整数に変換する文字列として)、および部署名の4つの入力を受け取ります。これらの値を使用してManagerインスタンスを作成します。次の3行を出力してください:- 直接アクセスしたマネージャーの名前(パブリックプロパティ)
getTeamInfo()を呼び出した結果getSalary()を呼び出した結果
このチャレンジはカプセル化の実践を示しています。名前は自由にアクセスでき、従業員IDは protected 可視性を通じて子クラスと共有され、給与は親クラスにロックされたままとなり、制御されたパブリックメソッドを通じてのみアクセス可能になります。
チートシート
PHPには、プロパティやメソッドにどこからアクセスできるかを制御するための3つのアクセス修飾子が用意されています。
| 修飾子 | 同一クラス内 | 子クラス内 | クラス外 |
|---|---|---|---|
public | 可能 | 可能 | 可能 |
protected | 可能 | 可能 | 不可 |
private | 可能 | 不可 | 不可 |
例:
<?php
class BankAccount {
public $accountHolder; // どこからでもアクセス可能
protected $accountNumber; // このクラスおよび子クラスからアクセス可能
private $balance; // このクラス内からのみアクセス可能
public function __construct($holder, $number, $balance) {
$this->accountHolder = $holder;
$this->accountNumber = $number;
$this->balance = $balance;
}
public function getBalance() {
return $this->balance;
}
}
$account = new BankAccount("John", "12345", 1000);
echo $account->accountHolder; // 動作する - public
echo $account->getBalance(); // 動作する - public メソッド
ベストプラクティス:
- 直接アクセスすべきではない内部データには
privateを使用する - 子クラスが必要とするデータには
protectedを使用する - 安全な外部アクセスに対してのみ
publicを使用する
自分で試してみよう
<?php
require_once 'Manager.php';
// 入力を読み込む
$name = trim(fgets(STDIN));
$employeeId = trim(fgets(STDIN));
$salary = intval(trim(fgets(STDIN)));
$department = trim(fgets(STDIN));
// TODO: 入力値を使用してManagerインスタンスを作成する
// TODO: マネージャーの名前を出力する(パブリックプロパティとして直接アクセス)
// TODO: getTeamInfo()の呼び出し結果を出力する
// TODO: getSalary()の呼び出し結果を出力する
?>このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。