1、 (違反里氏替換原則的反例子 )現(xiàn)需要完成一個兩數(shù)相減的功能,由類Subtraction來負(fù)
1、 (違反里氏替換原則的反例子 )現(xiàn)需要完成一個兩數(shù)相減的功能,由類Subtraction來負(fù)責(zé);需要增加一個新的功能:完成兩數(shù)相加,然后再與 10求和,由類 Add來負(fù)責(zé),所以類 Add繼承類 Subtraction后。調(diào)試運行此示例,分析程序運行得到錯誤結(jié)果的原因。
在這個例子中,Add類繼承了Subtraction類,但是它的新增功能addAndSumTo10并沒有對原有函數(shù)進行擴展或重載,而是直接調(diào)用了Subtraction類中的函數(shù),破壞了原有類的封裝性和穩(wěn)定性。這樣的設(shè)計不僅違反了里氏替換原則,而且可能導(dǎo)致程序出現(xiàn)錯誤結(jié)果,因為在調(diào)用addAndSumTo10函數(shù)時,實際上是調(diào)用了Subtraction類中的subtract函數(shù),并將其結(jié)果加上了10,而不是兩數(shù)相加再加10。因此,需要對Add類進行重新設(shè)計,或者將新增功能實現(xiàn)為一個新的獨立函數(shù),而不是直接調(diào)用原有函數(shù)。
2、分析程序:正方形不少長方形。在數(shù)學(xué)領(lǐng)域里,正方形毫無疑問是長方形,它是一個長寬相等的長方形。所以,我們開發(fā)的一個與幾何圖形相關(guān)的軟件系統(tǒng)中,讓正方形繼承自長方形是順利成章的事情。現(xiàn)在,我們截取該系統(tǒng)的一個代碼片段進行分析://長方形類 Rectangle:class Rectangle { ?double length; ?double width; ?public double getLength() { return length; } ? public void setLength(double height) { this.length = length; } ? ? public double getWidth() { return width; } ?public void setWidth(double width) { this.width = width; } }//正方形類 Square:class Square extends Rectangle { ?public void setWidth(double width) { ? ?super.setLength(width); ? ?super.setWidth(width); ? ?} ?public void setLength(double length) { ? ? super.setLength(length); ? ?super.setWidth(length); ? ? } }由于正方形的度和寬度必須相等,所以在方法 setLength和 setWidth中,對長度和寬度賦值相同。類 TestRectangle是我們的軟件系統(tǒng)中的一個組件,它有一個 resize方法要用到基類 Rectangle,resize方法的功能是模擬長方形寬度逐步增長的效果://測試類 TestRectangle:class TestRectangle { ? ?public void resize(Rectangle objRect) { ? ? ? ?while(objRect.getWidth() <= objRect.getLength()) { ? ? ? ?objRect.setWidth( ?objRect.getWidth () + 1 ); ? ? ? ?} ? ?}}分析程序的執(zhí)行結(jié)果
程序的執(zhí)行結(jié)果是將長方形的寬度逐步增加,直到寬度大于長度為止。這是因為在resize方法中,每次將長方形的寬度加1,直到寬度大于長度為止。由于正方形繼承了長方形,所以正方形也可以使用resize方法來模擬寬度的增長,但是由于正方形的寬度和長度相等,所以在正方形的setWidth和setLength方法中,只需要調(diào)用基類Rectangle的setWidth和setLength方法,并將寬度和長度設(shè)置為相同的值即可。
1、違反里氏替換原則的反例子:
class Subtraction {
public int subtract(int a, int b) {
return a - b;
}
}
class Add extends Subtraction {
public int addAndSumTo10(int a, int b) {
return super.subtract(a, b) + 10;
}
}
在這個例子中,Add類繼承了Subtraction類,但是其新增的功能addAndSumTo10并沒有符合里氏替換原則,因為它并沒有對原有函數(shù)進行擴展或重載,而是直接調(diào)用了Subtraction類中的函數(shù),破壞了原有類的封裝性和穩(wěn)定性。
2、正方形不少長方形:
這個例子雖然看起來符合“正方形是長方形”的邏輯,但是在程序?qū)崿F(xiàn)上出現(xiàn)了問題。因為長方形和正方形在尺寸和特性上有所不同,所以在代碼中直接讓正方形繼承長方形會導(dǎo)致難以維護和擴展的代碼。在這個例子中,如果想要對正方形類進行修改或擴展,可能會影響到長方形的使用,產(chǎn)生不必要的風(fēng)險。因此,更好的做法是將正方形和長方形視為兩個獨立的類,各自實現(xiàn)對應(yīng)的特性和方法,避免繼承帶來的復(fù)雜性和不確定性。