在 PHP 中,經過爲屬性或方法設置 public, protected 和 private 關鍵字能夠實現對屬性或方法的可見性控制。不過,經過 getter 和 setter 也能夠達到控制可見性的目的,而且在某些場景下它具有一些額外的好處。php
使用 getter和 setter 有如下好處:函數
另外,這是面向對象的基本設計原則中的開放/封閉原則。this
Bad:設計
class BankAccount { public $balance = 1000; } $bankAccount = new BankAccount(); // 買了一雙鞋... $bankAccount->balance -= 100;
Good:日誌
class BankAccount { private $balance; public function __construct($balance = 1000) { $this->balance = $balance; } //作一些事情 public function withdrawBalance($amount) { if ($amount > $this->balance) { throw new \Exception('Amount greater than available balance.'); } $this->balance -= $amount; } public function depositBalance($amount) { $this->balance += $amount; } public function getBalance() { return $this->balance; } } $bankAccount = new BankAccount(); // 買了一雙鞋... $bankAccount->withdrawBalance($shoesPrice); // 獲取結餘 $balance = $bankAccount->getBalance();
Bad:code
class Employee { public $name; public function __construct($name) { $this->name = $name; } } $employee = new Employee('John Doe'); echo 'Employee name: '.$employee->name; // Employee name: John Doe
Good:對象
class Employee { private $name; public function __construct($name) { $this->name = $name; } public function getName() { return $this->name; } } $employee = new Employee('John Doe'); echo 'Employee name: '.$employee->getName(); // Employee name: John Doe
這裏不是說不使用繼承,使用「組合模式」和使用「繼承」都有不少好的理由。繼承
這裏想說的是當你本能的要使用繼承時就想想「組合模式」是否能更好幫你的解決問題。get
那麼,你可能想知道,「何時應該用繼承?」, 這取決於你手頭上問題。it
如下幾點說明了何時使用繼承會更合適。
Bad:
class Employee { private $name; private $email; public function __construct($name, $email) { $this->name = $name; $this->email = $email; } // ... } // 由於僱員和稅收不是對等關係而是包含的關係 // 因此這裏應用組合比較合適 class EmployeeTaxData extends Employee { private $ssn; private $salary; public function __construct($name, $email, $ssn, $salary) { parent::__construct($name, $email); $this->ssn = $ssn; $this->salary = $salary; } // ... }
Good:
class EmployeeTaxData { private $ssn; private $salary; public function __construct($ssn, $salary) { $this->ssn = $ssn; $this->salary = $salary; } // ... } class Employee { private $name; private $email; private $taxData; public function __construct($name, $email) { $this->name = $name; $this->email = $email; } public function setTaxData($ssn, $salary) { $this->taxData = new EmployeeTaxData($ssn, $salary); } // ... }