[英]Does `instanceof` operator violate Liskov Substitution Principle?
[英]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.