我有一個模型抽象類,它聲明瞭一個項目列表。摘要有兩個抽象類。其中你可以添加新的項目到列表和一個根本不使用該列表,但除此之外的模型抽象類的其他行爲。在這種情況下,我可以違反LSP(Liskov替換)嗎?
我聲明瞭兩種方法來添加和刪除列表中的項目。很顯然,無論何時我想使用這些方法,我都需要將模型抽象與其子類一起施放。
在這種情況下,我可以違反LSP (Liskov substitution principle)嗎?或者有解決這個問題的辦法嗎?
我有一個模型抽象類,它聲明瞭一個項目列表。摘要有兩個抽象類。其中你可以添加新的項目到列表和一個根本不使用該列表,但除此之外的模型抽象類的其他行爲。在這種情況下,我可以違反LSP(Liskov替換)嗎?
我聲明瞭兩種方法來添加和刪除列表中的項目。很顯然,無論何時我想使用這些方法,我都需要將模型抽象與其子類一起施放。
在這種情況下,我可以違反LSP (Liskov substitution principle)嗎?或者有解決這個問題的辦法嗎?
我想你會違反LSP。
從Wikipedia page for LSP(即永遠是您的朋友):
「更正式地,里氏替換原則(LSP)是一種子類型關係的一個特定的定義,所謂的(強)行爲子類型」
「行爲子類型比在類型理論,這僅在參數類型和返回類型的協方差的逆變依賴定義函數典型亞型更強的概念。行爲子類型是一般平凡不可判定」
看起來類似於你的情況:
「違反LSP是正方形類從一個矩形類派生,假設二者的寬度和高度存在獲取和設置方法的典型例子。 Square類始終假設寬度與高度相等。如果在需要Rectangle的上下文中使用Square對象,則可能會發生意外的行爲,因爲Square的尺寸不能單獨修改(或者不應該)。這個問題不容易修正:如果我們可以在Square類中修改setter方法,以便它們保留Square不變量(即保持尺寸相等),那麼這些方法將削弱(違反)Rectangle設置器的後置條件,說明尺寸可以獨立修改。 LSP的違規行爲,像這樣的,可能會或可能不會在實踐中」
沒學過LSP,但生病說這
有投一直是壞的(不太理想)OO設計的標誌。
如果你想,你可以設置的東西太多,然後模型聲明爲正確的模型
同樣適用於Java集合API
Collection coll = new ArrayList();
((List) coll).set(3,"sdf");
是代碼,將工作,但只是寫的不好
應該offcourse一直
List coll = new ArrayList();
coll.set(3,"sdf");
使用你想要的具體類型
我明白LSP上的問題,但在這裏,它可能是這個問題解決了設計原因,Java有單繼承和多接口。
一個類可以只擴展另一個類。在C++中,情況並非如此,超類中可能存在衝突的名稱。多重繼承也給出了一些理論類型問題。
所以你必須把一個方面變成一個接口,並且可以從一個實現一個或多個接口的抽象類擴展。
當Square從Rectangle延伸並實現WidthEqualsHeight時,LSP保持不變。
請給我們展示一些代碼。它會更清晰。 – 2011-12-22 10:18:37
這聽起來像是上課不是要去這裏的路。繼承幾乎總是唯一有意義的,如果你可以透明地用基類來代替派生類。 – helpermethod 2011-12-22 10:35:04
違反Liskov替代原則幾乎不是一個好主意,所以你必須有一個非常有力的論證來證明這一點。 – Jesper 2011-12-22 10:35:06