PHP - 封裝



PHP 實現**封裝**,這是 OOP 的重要原則之一,它使用訪問控制關鍵字:**public、private** 和 **protected**。

封裝是指將物件的成員變數或屬性與外部環境隔離開來的機制,只允許透過類中提供的成員方法或函式進行控制訪問。

下圖說明了面向物件程式設計方法中封裝的原則。

PHP Encapsulation 1

PHP 的關鍵字列表包含以下關鍵字,這些關鍵字決定了物件的屬性和方法的可訪問性,這些物件是 PHP 中類的例項:

  • **Public** - 類成員可以從任何地方訪問,即使是在類作用域之外,但只能透過物件引用訪問。

  • **Private** - 類成員只能在類內部訪問。它阻止外部類訪問成員,即使是透過類例項的引用。

  • **Protected** - 成員只能在類及其子類中訪問,其他地方都不能訪問。

這三個關鍵字“**public、private** 和 **protected**”通常稱為訪問修飾符。它們也稱為可見性模式,因為它們決定某個類成員的可用程度。

公共成員

在 PHP 中,類成員(成員變數和成員函式)預設是公共的,除非另有說明。

示例

在下面的程式中,物件的成員變數 title 和 price 可以在類外部自由訪問,因為它們預設為公共的,除非另有說明。

<?php
   class Person {
   
      /* Member variables */
      var $name;
      var $age;

      /*Constructor*/
      function __construct(string $param1="Ravi", int $param2=28) {
         $this->name = $param1;
         $this->age = $param2;
      }

      function getName() {
         echo "Name: $this->name" . PHP_EOL;;
      }
      function getAge() {
         echo "Age: $this->age" . PHP_EOL;;
      }
   }
   $b1 = new Person();
   $b1->getName();
   $b1->getAge();
   echo "Name : $b1->name Age: $b1->age" . PHP_EOL;
?>

它將產生以下**輸出**:

Name: Ravi
Age: 28
Name : Ravi Age: 28

**注意**,所有類成員的屬性預設都是公共的,如果需要,您可以顯式地將它們宣告為公共的。因此,例項方法 getName() 和 getAge() 可以從類外部呼叫。

由於屬性 name 和 age 也是公共的,因此它們也可以從類外部訪問,這與封裝的原則不符。

私有成員

如上所述,封裝的原則要求不應直接訪問成員變數。只有方法才能訪問資料成員。因此,我們需要將成員變數設為私有,將方法設為公共。

示例

讓我們將 name 和 age 屬性的宣告更改為私有,並執行以下 PHP 指令碼:

<?php
   class Person {
   
      /* Member variables */
      private $name;
      private $age;

      /*Constructor*/
      function __construct(string $param1="Ravi", int $param2=28) {
         $this->name = $param1;
         $this->age = $param2;
      }

      public function getName() {
         echo "Name: $this->name" . PHP_EOL;;
      }

      public function getAge(){
         echo "Age: $this->age" . PHP_EOL;;
      }
   }

   $b1 = new Person();
   $b1->getName();
   $b1->getAge();
   echo "Name : $b1->name Age: $b1->age" . PHP_EOL;
?>

它將產生以下**輸出**:

Name: Ravi
Age: 28
PHP Fatal error:  Uncaught Error: Cannot access private property Person::$name in person.php:27

錯誤訊息說明了私有屬性無法從公共作用域訪問的原因。

受保護的成員

指定受保護訪問對類成員的影響在類繼承的情況下有效。我們知道公共成員可以在類外部的任何地方訪問,而私有成員則被拒絕在類外部的任何地方訪問。

**protected** 關鍵字允許訪問同一類的物件及其繼承類的物件,而拒絕訪問任何其他環境。

示例

讓我們繼承 person 類並定義一個 student 類。我們將 name 屬性從私有更改為受保護。student 類有一個新的公共方法 getDetails(),它列印 name 和 age 屬性的值。

Person 類

<?php
class Person {

   /* Member variables */
   protected $name;
   private $age;

   /*Constructor*/
   function __construct(string $param1="Ravi", int $param2=28) {
      $this->name = $param1;
      $this->age = $param2;
   }

   public function getName(){
      echo "Name: $this->name" . PHP_EOL;;
   }

   public function getAge() {
      echo "Age: $this->age" . PHP_EOL;;
   }
}

Student 類

class student extends Person {
   public function getDetails() {
      echo "My Name: $this->name" . PHP_EOL;
      echo "My age: $this->age" . PHP_EOL;
   }
}
$s1 = new student();
$s1->getDetails();
?>

它將產生以下**輸出**:

My Name: Ravi
PHP Warning:  Undefined property: student::$age in person.php on line 28
My age:

下表說明了 PHP 中類成員的可訪問性規則:

PHP Encapsulation 2
廣告