首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 可視性關鍵字深度解析:public、protected、private 差異與存取規則

     編輯:PHP 相關知識

PHP 可視性關鍵字深度解析:public、protected、private 差異與存取規則

封裝是物件導向核心特性,PHP 透過 public、protected、private 三種可視性控制屬性與方法的存取權限。本文系統整理各種呼叫情境下的存取規則,並提供完整測試代碼。

一、快速對照表

存取方式publicprotectedprivate
類外部:ClassName::staticMethod()✅❌❌
類外部:$obj->method()✅❌❌
類內部:self::staticMethod()✅✅✅
子類別:parent::staticMethod()✅✅❌
子類別實例:$obj->method()✅✅❌

二、詳細情境與代碼驗證

1. 直接呼叫 (類名稱/實例)

<?php
class A {
    public static $name = 'A 的靜態屬性';
    public static function pubStatic() { echo "public static\n"; }
    protected static function proStatic() { echo "protected static\n"; }
    private static function priStatic() { echo "private static\n"; }
}

// 類名稱呼叫靜態方法
A::pubStatic(); // ✅
// A::proStatic(); // ❌ Fatal error
// A::priStatic(); // ❌ Fatal error

// 實例呼叫 (靜態方法也可用實例呼叫)
$a = new A();
$a->pubStatic(); // ✅
// $a->proStatic(); // ❌
// $a->priStatic(); // ❌
?>

2. 類內部透過 self:: 呼叫

<?php
class B {
    public static function test() {
        self::pub();   // ✅
        self::pro();   // ✅
        self::pri();   // ✅
    }
    public static function pub() { echo "pub\n"; }
    protected static function pro() { echo "pro\n"; }
    private static function pri() { echo "pri\n"; }
}
B::test(); // 輸出 pub, pro, pri
?>

結論:self:: 在同一類別內可存取所有可視性成員。

3. 子類別透過 parent:: 呼叫父類別

<?php
class ParentClass {
    public static function pub() { echo "parent pub\n"; }
    protected static function pro() { echo "parent pro\n"; }
    private static function pri() { echo "parent pri\n"; }
}

class ChildClass extends ParentClass {
    public static function test() {
        parent::pub();  // ✅
        parent::pro();  // ✅
        // parent::pri(); // ❌ Fatal error
    }
}
ChildClass::test();
?>

結論:子類別可透過 parent:: 存取父類別 public 與 protected 靜態成員,不可存取 private。

4. 子類別實例呼叫繼承方法

<?php
class Base {
    public function pub() { echo "pub\n"; }
    protected function pro() { echo "pro\n"; }
    private function pri() { echo "pri\n"; }
}

class Derived extends Base {
    public function test() {
        $this->pub();  // ✅
        $this->pro();  // ✅
        // $this->pri(); // ❌ Fatal error
    }
}
$d = new Derived();
$d->test();
$d->pub();  // ✅
// $d->pro(); // ❌ (外部不可呼叫 protected)
?>

三、最佳實務建議

  1. 預設用 private:封裝內部實作細節,僅暴露必要的 public 介面。
  2. 繼承用 protected:預期子類別需覆寫或呼叫的內部方法/屬性。
  3. 介面用 public:定義類別對外契約,包含建構子、主要業務方法。
  4. 避免濫用 static:靜態成員屬於類別而非實例,易造成耦合與測試困難,僅用於真正的「類別層級」資料或工具方法。
  5. 屬性一律私有,提供 getter/setter:符合資訊隱藏原則,未來易於加入驗證邏輯。

四、PHP 8 新特性:readonly 屬性

<?php
class User {
    public readonly string $id; // 初始化後不可修改
    public function __construct(string $id) {
        $this->id = $id;
    }
}
$user = new User('123');
// $user->id = '456'; // ❌ Error: Cannot modify readonly property
?>

readonly 結合 public 可替代傳統「private 屬性 + public getter」模式,程式碼更簡潔且語意明確。

掌握可視性規則是寫出高內聚、低耦合 PHP 代碼的基礎。建議在 Code Review 時檢查每個成員的可視性是否符合「最小權限原則」。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved