程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 從OO封裝談起

從OO封裝談起

編輯:關於.NET

在我們熟悉的OO語言中,可以通過private、protected、public等訪問控制修飾符將數據 和方法分為內部可見、子類可見、外部可見等不同訪問級別。本文從一個較為特別的封裝相 關例子出發,討論封裝、類型系統、契約式編程相關話題。我們先從例子開始:

public class Person {
    private int _money;

    public void Change(amount){
        this._money += amount;
    }

    public void Exchange(Person p, int amount) {
        p._money -= amount;
        this._money += amount;
    }
}

基於”沒有經過我允許,不許直接動我的錢”的假設,Person類把變量_money 作為private成員,並提供public的Change方法。但有爭議的地方在於,在Exchange中我們可 以直接訪問並修改p._money。請注意上面的代碼在C#編譯器下是完全合法的,類似的代碼在 C++和Java下也一樣。我在第一次接觸這個例子的時候,起初有些疑惑編譯器是對還是錯?後 來想了一個理由“OO的封裝是基於類的,而非對象”來說服自己。

現在,對這個問題有了更新的認識,希望和大家討論。上面的例子中,我們的理想情況是 Person對象本身可以直接訪問自己的_money變量,其他Person對象不能直接訪問。但OO的封 裝實現必須依賴編譯器進行靜態訪問權限檢查;既然是靜態那就只能應用到類型,無法應用 到對象實例。因此,在上例中C#編譯器無法確認p和this是否引用同一對象或不同對象。從這 個意義上講,OO的封裝只到類這一級別與其說是設計考慮不如說是不得以的選擇。

從更大的層面上講,這個例子不僅和OO封裝相關,本質上是反映了程序語言類型系統的作 用和局限。程序語言的類型系統是一種靜態的跟蹤和檢查機制,它能保證程序的類型正確性 ,但無法保證語義正確性(理想情況下,上面的例子中,p如果和this是同一對象那麼語義正 確;否則,語義錯誤)。換句話說,類型正確性可以通過類型系統用形式化的方式進行表達 和檢查。那麼語義正確性應該如何來保證呢?有沒有形式化的方式呢?答案也許就像下面這 樣:

public class Person {
    private int _money;

    public void Change(amount){
        this._money += amount;
    }

    public void Exchange(Person p, int amount) {
        Assert(this != p);
        p.Change(-amount);
        this._money += amount;
    }
}

增加Assert斷言,就是希望從形式上保證語義的正確性。我的理解是:我們需要一種形式 化的方式保證語義的正確性。這是不是就是所謂契約式編程的初衷呢?希望高手指點!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved