Menu
Coddy logo textTech

Public, Protected, Private

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

カプセル化の章へようこそ!カプセル化とは、クラスの内部データへのアクセスを制御することです。PHPは、プロパティやメソッドがどこからアクセスできるかを決定する3つのアクセス修飾子を提供しています:publicprotected、および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 に対しても同様です。この保護により、機密データは制御されたメソッドを通じてのみ変更できることが保証されます。

修飾子同一クラス子クラス外部
publicYesYesYes
protectedYesYesNo
privateYesNoNo

重要なポイント: 直接アクセスすべきではない内部データには private を使用し、子クラスが必要とするデータには protected を、そして安全な外部アクセスにのみ public を使用してください。

challenge icon

チャレンジ

簡単

アクセス修飾子がどのように機密データを保護するかを実証する、安全な従業員管理システムを構築しましょう。クラス内、子クラス内、または外部からといった、コードが実行されている場所に応じて、異なるレベルの情報にアクセスできるクラス階層を作成します。

コードは3つのファイルに分けて構成します:

  • Employee.php — 適切な可視性レベルで従業員データを管理する Employee クラスを作成します。クラスには以下を含める必要があります:
    • 従業員名のための public プロパティ $name(誰でも見ることができます)
    • 内部IDのための protected プロパティ $employeeId(子クラスで必要になります)
    • 機密性の高い給与情報のための private プロパティ $salary(このクラスのみが直接アクセスできます)
    コンストラクタはこれら3つの値を受け取り、割り当てる必要があります。プライベートな給与を返すパブリックメソッド getSalary() を追加してください。これが保護されたデータにアクセスするための制御された方法です。また、"[name] works here" を返すパブリックメソッド getPublicInfo() も追加してください。
  • Manager.phpEmployee を継承する 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()の呼び出し結果を出力する
?>
quiz icon腕試し

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

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