封裝 (物件導向程式設計)
在物件導向程式設計方法中,封裝(英語:Encapsulation)是指,一種將抽象性函式介面的實作細節部份包裝、隱藏起來的方法。同時,它也是一種防止外界呼叫端,去存取物件內部實作細節的手段,這個手段是由程式語言本身來提供的。封裝被視為是物件導向的四項原則之一。
![](http://upload.wikimedia.org/wikipedia/commons/thumb/8/82/CPT-OOP-interfaces.svg/220px-CPT-OOP-interfaces.svg.png)
適當的封裝,可以將物件使用介面的程式實作部份隱藏起來,不讓使用者看到,同時確保使用者無法任意更改物件內部的重要資料,若想接觸資料只能通過公開接入方法(Publicly accessible methods)的方式( 如:"getters" 和"setters")。它可以讓程式碼更容易理解與維護,也加強了程式碼的安全性。[來源請求]
解釋
編輯在面向對象的語言裡,封裝往往指以下兩個相關聯但是獨立的概念,有時候這兩者是存在因果關係。[1][2]
一些編程語言的研究者和學者將定義①或者定義①+②作為辨認一門語言是否為面向對象語言的標準之一。一些編程語言提供了閉包作為封裝,但是這種功能不屬於面向對象的範疇。
在許多編程語言裡,組件並不會自動隱藏並且能夠被重寫,因此,一些傾向於定義②的人會將信息隱藏(information hiding)作為一個單獨的定義③列舉出來。
在使用類的大多面向對象的編程語言中,雖然封裝是被支持的,但是仍有其他替代品可以選擇。
《Design Patterns》的作者們曾經大篇幅地討論封裝和繼承的矛盾。根據他們自身的經驗,設計師們濫用繼承。他們認為繼承將破壞封裝,考慮父類的實現細節將暴露給子類。[7]
父類的內部實現對於子類來說是不透明的(實現一個子類時, 你需要了解父類的實現細節, 以此決定是否需要重寫某個方法)。[8]同時,一旦父類被修改,因為子類依賴着父類,所以子類的實現也需要被重新審視。
信息隱藏
編輯封裝可以隱藏成員變量以及成員函數,對象的內部實現通常被隱藏,並用定義代替。舉個例子,僅僅對象自身的方法能夠直接接觸或者操作這些成員變量。隱藏對象內部信息能供保證一致性:當用戶擅自修改內部部件的數據,這可能造成內部狀態不一致或者不可用;隱藏對象內部信息能阻止這種後果。一個眾所周知的好處是,降低系統的複雜度和提高健壯性。
大多數語言(如:C++、C#、 Delphi、Java)通過設定等級去控制內部信息隱藏,經典的是通過保留字 public
暴露信息和 private
隱藏信息。一些語言(如: Smalltalk 和 Ruby )只允許對象去訪問隱藏信息。
程式範例
編輯C#範例
編輯這是一段C#代碼,演示了如何使用private
關鍵字限制變量的訪問:
namespace Encapsulation
{
class Program
{
public class Account
{
private decimal accountBalance = 500.00m;
public decimal CheckBalance()
{
return accountBalance;
}
}
static void Main()
{
Account myAccount = new Account();
decimal myBalance = myAccount.CheckBalance();
/* Main方法能够通过public的“CheckBalance”方法确认账户余额,但是不能更改它 */
}
}
}
JAVA範例
編輯下面是Java的演示程序:
public class Employee {
private BigDecimal salary = new BigDecimal(50000.00);
public BigDecimal getSalary() {
return salary;
}
public static void main() {
Employee e = new Employee();
BigDecimal sal = e.getSalary();
}
}
下面是Python的要給實例,Python並不支持隱藏變量。然而約定俗成,_var
形式的變量被認為是私有變量。
class Car:
def __init__(self):
self._maxspeed = 200
def drive(self):
print(f'maximum speed is {self._maxspeed}')
redcar = Car()
redcar.drive() # 打印 'maximum speed is 200'
redcar._maxspeed = 10
redcar.drive() # 打印 'maximum speed is 10'
參考文獻
編輯- ^ Scott, Michael Lee. Programming language pragmatics 2. Morgan Kaufmann. 2006: 481. ISBN 978-0-12-633951-2.
Encapsulation mechanisms enable the programmer to group data and the subroutines that operate on them together in one place, and to hide irrelevant details from the users of an abstraction.
- ^ Dale, Nell B.; Weems, Chip. Programming and problem solving with Java 2nd. Jones & Bartlett. 2007: 396. ISBN 978-0-7637-3402-2.
- ^ Mitchell, John C. Concepts in programming languages. Cambridge University Press. 2003: 522. ISBN 978-0-521-78098-8.
- ^ Pierce, Benjamin. Types and Programming Languages. MIT Press. 2002: 266. ISBN 978-0-262-16209-8.
- ^ Rogers, Wm. Paul. Encapsulation is not information hiding. JavaWorld. 18 May 2001 [2019-11-22]. (原始內容存檔於2013-10-29).
- ^ Connolly, Thomas M.; Begg, Carolyn E. Ch. 25: Introduction to Object DMBS § Object-oriented concepts. Database systems: a practical approach to design, implementation, and management 4th. Pearson Education. 2005: 814. ISBN 978-0-321-21025-8.
- ^ Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John. Design Patterns. Addison-Wesley. 1994. ISBN 978-0-201-63361-0.
- ^ 蕭蕭. 怎样理解“组合优于继承”以及“OO的反模块化”,在这些方面FP具体来说有什么优势?. 2017-06-09 [2019-11-22]. (原始內容存檔於2020-02-04) (中文(簡體)).