| 導購 | 订阅 | 在线投稿
分享
 
 
 

一些面向對象的設計法則(4)

來源:互聯網  2008-05-31 11:18:15  評論

法則4:Liskov替換法則(LSP)

使用指向基類(超類)的引用的函數,必須能夠在不知道具體派生類(子類)對象類型的情況下使用它們。

[ Function Thar Use Referennces To Base(Super) Classes Must Be Able To Use Objects

Of Derived(Sub) Classes Without Knowing It ]

Liskov替換法則

1.顯而易見,Liskov替換法則(LSP)是根據我所熟知的"多態"而得出的。

2.例如:

方法drawShape應該可與Sharp超類的任何子類一起工作(或者,若Sharp爲java接口,則該方法可與任何實現了Sharp接口的類一起工作)

但是當我們在實現子類時必須要謹慎對待,以確保我們不會無意中違反了LSP。

3.若一個函數未能滿足LSP,那麽可能是因爲它顯式地引用了超類的一些或所有子類。這樣的函數也違反了OCP,因爲當我們創建一個新的子類時,會不得不進行代碼的修改。

LSP示例

1. 考慮下面Rectangle類:

一些面向對象的設計法則(4)

2.現在,Square類會如何呢?顯然,一個正方形是一個四邊形,因此Square類應該從Rectangle類派生而來,對否?讓我們看一看!

3.觀察可得:

a.正方形不需要將高和寬都作爲屬性,但是總之它將繼續自Rectangle。因此,每一個Square對象會浪費一點內存,但這並不是一個主要問題。

b.繼續而來的setWidth()和setHeight()方法對于Square而言並非真正地適合,因爲一個正方形的高和寬是相同。因此我們將需要重寫setWidth()和setHeight()方法。不得不重寫這些簡單的方法有可能是一種不恰當的繼續使用方式。

3.Square類如下:

一些面向對象的設計法則(4)

4. 看起來都還不錯。但是讓我們檢驗一下!

一些面向對象的設計法則(4)

一些面向對象的設計法則(4)

5. 測試程序輸出:

一些面向對象的設計法則(4)

6.看上去似乎我們違反了LSP!

7.這裏的問題出在哪裏呢?編寫testLsp()方法的程序員做了一個合理的假設,即改變Rectangle的寬而保持它的高不變。

8.在將一個Square對象傳遞給這樣一個方法時産生了問題,顯然是違反了LSP

9.Square和Rectangle類是相互一致和合法的。盡管程序員對基類作了合理的假設,但其所編寫的方法仍然會導致設計模型的失敗。

10.不能孤立地去看待解決方案,必須根據設計用戶所做的合理假設來看待它們。

11. 一個數學意義上的正方形可能是一個四邊形,但是一個Square對象不是一個Rectangle對象,因爲一個Square對象的行爲與一個Rectangle對象的行爲是不一致的!

12.從行爲上來說,一個Square不是一個Rectangle!一個Square對象與一個Rectangle對象之間不具有多態的特征。

總結

1.Liskov替換法則(LSP)清楚地表明了ISA關系全部都是與行爲有關的。

2.爲了保持LSP(並與開放-封閉法則一起),所有子類必須符合使用基類的client所期望的行爲。

3.一個子類型不得具有比基類型(base type)更多的限制,可能這對于基類型來說是合法的,但是可能會因爲違反子類型的其中一個額外限制,從而違反了LSP!

4.LSP保證一個子類總是能夠被用在其基類可以出現的地方!

  法則4:Liskov替換法則(LSP)      使用指向基類(超類)的引用的函數,必須能夠在不知道具體派生類(子類)對象類型的情況下使用它們。      [ Function Thar Use Referennces To Base(Super) Classes Must Be Able To Use Objects   Of Derived(Sub) Classes Without Knowing It ]                           Liskov替換法則                     1.顯而易見,Liskov替換法則(LSP)是根據我所熟知的"多態"而得出的。      2.例如:            方法drawShape應該可與Sharp超類的任何子類一起工作(或者,若Sharp爲java接口,則該方法可與任何實現了Sharp接口的類一起工作)      但是當我們在實現子類時必須要謹慎對待,以確保我們不會無意中違反了LSP。                           3.若一個函數未能滿足LSP,那麽可能是因爲它顯式地引用了超類的一些或所有子類。這樣的函數也違反了OCP,因爲當我們創建一個新的子類時,會不得不進行代碼的修改。                              LSP示例                     1. 考慮下面Rectangle類:       [url=/bbs/detail_1758845.html][img]http://image.wangchao.net.cn/it/1323510361979.gif[/img][/url]      2.現在,Square類會如何呢?顯然,一個正方形是一個四邊形,因此Square類應該從Rectangle類派生而來,對否?讓我們看一看!      3.觀察可得:      a.正方形不需要將高和寬都作爲屬性,但是總之它將繼續自Rectangle。因此,每一個Square對象會浪費一點內存,但這並不是一個主要問題。      b.繼續而來的setWidth()和setHeight()方法對于Square而言並非真正地適合,因爲一個正方形的高和寬是相同。因此我們將需要重寫setWidth()和setHeight()方法。不得不重寫這些簡單的方法有可能是一種不恰當的繼續使用方式。            3.Square類如下:       [url=/bbs/detail_1758845.html][img]http://image.wangchao.net.cn/it/1323510362091.gif[/img][/url]      4. 看起來都還不錯。但是讓我們檢驗一下!       [url=/bbs/detail_1758845.html][img]http://image.wangchao.net.cn/it/1323510362272.gif[/img][/url]       [url=/bbs/detail_1758845.html][img]http://image.wangchao.net.cn/it/1323510362369.gif[/img][/url]      5. 測試程序輸出:      [url=/bbs/detail_1758845.html][img]http://image.wangchao.net.cn/it/1323510365459.gif[/img][/url]      6.看上去似乎我們違反了LSP!            7.這裏的問題出在哪裏呢?編寫testLsp()方法的程序員做了一個合理的假設,即改變Rectangle的寬而保持它的高不變。      8.在將一個Square對象傳遞給這樣一個方法時産生了問題,顯然是違反了LSP      9.Square和Rectangle類是相互一致和合法的。盡管程序員對基類作了合理的假設,但其所編寫的方法仍然會導致設計模型的失敗。      10.不能孤立地去看待解決方案,必須根據設計用戶所做的合理假設來看待它們。            11. 一個數學意義上的正方形可能是一個四邊形,但是一個Square對象不是一個Rectangle對象,因爲一個Square對象的行爲與一個Rectangle對象的行爲是不一致的!      12.從行爲上來說,一個Square不是一個Rectangle!一個Square對象與一個Rectangle對象之間不具有多態的特征。                                          總結                     1.Liskov替換法則(LSP)清楚地表明了ISA關系全部都是與行爲有關的。      2.爲了保持LSP(並與開放-封閉法則一起),所有子類必須符合使用基類的client所期望的行爲。      3.一個子類型不得具有比基類型(base type)更多的限制,可能這對于基類型來說是合法的,但是可能會因爲違反子類型的其中一個額外限制,從而違反了LSP!      4.LSP保證一個子類總是能夠被用在其基類可以出現的地方!
󰈣󰈤
王朝萬家燈火計劃
期待原創作者加盟
 
 
 
>>返回首頁<<
 
 
 
 
 熱帖排行
 
王朝網路微信公眾號
微信掃碼關註本站公眾號 wangchaonetcn
 
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有