<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 面向對象設計原則之里氏代換原則 里氏代換原則由2008年圖靈獎得主、美國第一位計算機科學女博士Barbara Liskov教授和卡內基·梅隆大學Jeannette Wing教授于1994年提出。其嚴格表述如下:如果對每一個類型為S的對象o1,都有類型為T的對象o2,使得以T定義的所有程序P在所有的對象o1代換o2時,程序P的行為沒有變化,那么類型S是類型T的子類型。這個定義比較拗口且難以理解,因此我們一般使用它的另一個通俗版定義: 里氏代換原則(Liskov Substitution Principle, LSP):所有引用基類(父類)的地方必須能透明地使用其子類的對象。 里氏代換原則告訴我們,在軟件中將一個基類對象替換成它的子類對象,程序將不會產生任何錯誤和異常,反過來則不成立,如果一個軟件實體使用的是一個子類對象的話,那么它不一定能夠使用基類對象。例如:我喜歡動物,那我一定喜歡狗,因為狗是動物的子類;但是我喜歡狗,不能據此斷定我喜歡動物,因為我并不喜歡老鼠,雖然它也是動物。 例如有兩個類,一個類為BaseClass,另一個是SubClass類,并且SubClass類是BaseClass類的子類,那么一個方法如果可以接受一個BaseClass類型的基類對象base的話,如:method1(base),那么它必然可以接受一個BaseClass類型的子類對象sub,method1(sub)能夠正常運行。反過來的代換不成立,如一個方法method2接受BaseClass類型的子類對象sub為參數:method2(sub),那么一般而言不可以有method2(base),除非是重載方法。 里氏代換原則是實現開閉原則的重要方式之一,由于使用基類對象的地方都可以使用子類對象,因此在程序中盡量使用基類類型來對對象進行定義,而在運行時再確定其子類類型,用子類對象來替換父類對象。 在使用里氏代換原則時需要注意如下幾個問題: (1)子類的所有方法必須在父類中聲明,或子類必須實現父類中聲明的所有方法。根據里氏代換原則,為了保證系統的擴展性,在程序中通常使用父類來進行定義,如果一個方法只存在子類中,在父類中不提供相應的聲明,則無法在以父類定義的對象中使用該方法。 (2) 我們在運用里氏代換原則時,盡量把父類設計為抽象類或者接口,讓子類繼承父類或實現父接口,并實現在父類中聲明的方法,運行時,子類實例替換父類實例,我們可以很方便地擴展系統的功能,同時無須修改原有子類的代碼,增加新的功能可以通過增加一個新的子類來實現。里氏代換原則是開閉原則的具體實現手段之一。 (3) Java語言中,在編譯階段,Java編譯器會檢查一個程序是否符合里氏代換原則,這是一個與實現無關的、純語法意義上的檢查,但Java編譯器的檢查是有局限的。 在Sunny軟件公司開發的CRM系統中,客戶(Customer)可以分為VIP客戶(VIPCustomer)和普通客戶(CommonCustomer)兩類,系統需要提供一個發送Email的功能,原始設計方案如圖1所示: 圖1原始結構圖 ![](http://my.csdn.net/uploads/201205/06/1336312710_1412.jpg) 在對系統進行進一步分析后發現,無論是普通客戶還是VIP客戶,發送郵件的過程都是相同的,也就是說兩個send()方法中的代碼重復,而且在本系統中還將增加新類型的客戶。為了讓系統具有更好的擴展性,同時減少代碼重復,使用里氏代換原則對其進行重構。 在本實例中,可以考慮增加一個新的抽象客戶類Customer,而將CommonCustomer和VIPCustomer類作為其子類,郵件發送類EmailSender類針對抽象客戶類Customer編程,根據里氏代換原則,能夠接受基類對象的地方必然能夠接受子類對象,因此將EmailSender中的send()方法的參數類型改為Customer,如果需要增加新類型的客戶,只需將其作為Customer類的子類即可。重構后的結構如圖2所示: ![](http://my.csdn.net/uploads/201205/06/1336312720_2300.jpg) 圖2 重構后的結構圖 里氏代換原則是實現開閉原則的重要方式之一。在本實例中,在傳遞參數時使用基類對象,除此以外,在定義成員變量、定義局部變量、確定方法返回類型時都可使用里氏代換原則。針對基類編程,在程序運行時再確定具體子類。 擴展 里氏代換原則以Barbara Liskov(芭芭拉·利斯科夫)教授的姓氏命名。芭芭拉·利斯科夫:美國計算機科學家,2008年圖靈獎得主,2004年約翰·馮諾依曼獎得主,美國工程院院士,美國藝術與科學院院士,美國計算機協會會士,麻省理工學院電子電氣與計算機科學系教授,美國第一位計算機科學女博士。 ![](http://my.csdn.net/uploads/201205/06/1336312647_8598.jpg)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看