[英]Why weakening a precondition does not violate Liskov substitution principle
[英]Does omitting super() and/or *weakening* preconditions violate the Liskov Substitution Principle?
我最近一直在深入研究一些SOLID設計原則,我從一個來源獲得的一些信息最初對我有意義,但基於我已經能夠找到的針對thr LSP的嚴格定義,它似乎就是這樣的信息可能不正確。 信息具體是:
1)在重寫方法上沒有回調到super()會違反LSP(或者至少會打開你的違規行為),因為基類的行為可能會在某些時候發生變化,而你的子類可能會以導致子類不再可替代父類。 這對我來說似乎有意義,但是如果有人可以詳細說明/給出一些關於什么時候不適合不回電話的信息那就太棒了。
2)子類的限制不應低於父類。 示例是:如果您的父類只接受正整數,那么您創建一個接受正負int的子類。 因此,孩子應該在父母的位置上工作正常,但在這種情況下,孩子不能委托給超級。
我認為這是有道理的,但LSP上的信息似乎恰恰相反:孩子無法強化前提條件。 兩者似乎都對我有意義,但利斯科夫只是說前提條件不能加強,后置條件不能削弱。 有人可以幫助我這個嗎?
1)情況,當不適合不回電話時
通常(但並非總是)這種情況意味着類層次結構設計出了問題。
如果子方法接受正確的輸入類型並返回正確的輸出類型,則不調用超類實現不會違反LSP。 它只表明問題的可能性。
當你不調用super方法時,這是一個絕對有效的例子:
class Animal
void eat(Food food)
// Eat the food
class Cat extends Animal
void meow()
// Say meow
class AnimalOwner
Animal findAPet()
return new Animal()
class CatOwner
// we can return the subclass of Animal here
Cat findAPet()
return new Cat() // We don't need to use the parent implementation
這里CatOwner::findAPet()
返回一個Cat
(一個Animal
子類),這在LSP方面是有效的,我們不調用父實現。
請注意,調用父實現並不能保證您不會遇到與不調用它時相同的問題。
考慮這個例子:
class Child
Output doSomething()
parent = super::doSomething()
if parent->isNotGood():
return new OutputSubclass() // We called super, but we return
// something different, might be not safe
else:
return parent // We called super and return
// the same value, safe
2)“在子類型中不能加強先決條件”。 這也意味着前提條件(與輸入參數相關的期望)可以保持不變或被削弱。 在你提到的例子中,前提條件實際上被削弱了,所以沒有沖突:
Parent::doSomething(PositiveInteger value) // Only positive integers
Child::doSomething(Integer value) // Positive or negative integers,
// pre-condition is weaker
// (covers wider area of values)
不正確的是第一句話:“子類不應該比父母更少限制”。 當我們討論前置條件(輸入參數)時,子類可以減少限制,這就是示例中顯示的內容。
Liskov替換原則要求您可以在期望基類型時使用子類型。 為此,您必須遵守基本類型的合同。 對於具有方法f,前提條件Pre,postcondition Post和不變I的基類B,這意味着
我會考慮顯式調用基類實現代碼氣味(構造函數除外)。 使用te,plate方法模式 (或C ++中的非虛擬接口 )來強制執行基類合約要好得多。 在Python中,這看起來像:
class Base:
def publicMethod(self, x):
// do something
self.templateMethod(x)
// do something else
def templateMethod(self, x):
// has to be overriden by sub-classes
// it provides extension hooks, but
// publicMethod ensures that the overall
// functionality is correct
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.