簡體   English   中英

抽象屬性是否違反了 Liskov 替換原則?

[英]Do abstract properties violate the Liskov substitution principle?

假設我有一個抽象的 class 像:

public abstract class Pet {
    private final String name;
    public Pet(String name) { 
        this.name = name 
    };

    public abstract boolean getsSpecialTreatment();
}

public final class Dog extends Pet {
    @Override public boolean getsSpecialTreatment() { return true; }
}

public final class Cat extends Pet {
    @Override public boolean getsSpecialTreatment() { return false; }
}

我的程序會根據是否設置了特殊處理標志來區別對待Pet 我的問題是這是否算作違反了 Liskov 替代原則,該原則指出:

[...] 在計算機程序中,如果 S 是 T 的子類型,那么 T 類型的對象可以被 S 類型的對象替換 [...]而不會改變該程序的任何期望屬性(正確性,執行的任務) , ETC。)。

在這種情況下,這些類的用戶可能會寫:

...
if (pet.getsSpecialTreatment()) {
    // special treatment
    ...
} else {
    // normal treatment
    ...
}
...

此代碼適用於這兩種情況,因此您不會違反 LSP。 但是,如果你有

public class UnknownAnimal extends Pet {
    @Override public boolean getsSpecialTreatment() {
        throw new UnsupportedOperationException("Unknown species"); 
    }
}

那么您將違反 LSP,因為現有代碼在使用UnknownAnimal實例時會中斷。

不會。程序中對該方法的任何使用都將基於返回值做出后續決策,就像任何其他方法一樣。 由於該方法存在的本質,任何程序都不應該對其結果做出假設。 因此,此方法返回的值的變化不應該改變程序的屬性。

首先,強烈反對你對貓的歧視!

現在,當程序員調用所謂的“里氏替換原則”時,他們並不是真正在談論它的學術意義。 我們一定是在某種非正式的、粗俗的、卑鄙的意義上使用它。

那是什么意思? 我發現它只不過是要求子類必須符合超級 class 設定的合同。 所以真的很無趣。 人們引用這句話只是為了狂熱。

這取決於合同。 也就是說,使用您的類的代碼必須獲得一致的行為,無論它使用的是什么類型的派生。

如果合同規定“getSpecialTreatment”總是返回 true,那么您將在派生的 class 中違反這一點。

如果合同規定“getSpecialTreatment”返回確定 blabla. 的 boolean 值,那么您沒有違反 LSP。

如果您引入了基礎 class 中不存在的附加約束,則可能違反 LSP。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM