里氏替换原则是SOLID原则之一。我已经多次阅读了这个原则,并试图理解它。
以下是我的理解:
该原则与类层次结构中的强行为契约有关。子类型应能够替换超类型,而不违反契约。
我也阅读了其他文章,并对此问题感到有些困惑。 Collections.unmodifiableXXX()
方法是否违反LSP?
以上摘自上述文章的一段:
换句话说,通过其基类接口使用对象时,用户仅知道基类的前置条件和后置条件。因此,派生对象不得期望这样的用户遵守比基类要求更严格的前置条件。
我为什么这么想?
在此之前
class SomeClass{
public List<Integer> list(){
return new ArrayList<Integer>(); //this is dumb but works
}
}
之后
class SomeClass{
public List<Integer> list(){
return Collections.unmodifiableList(new ArrayList<Integer>()); //change in implementation
}
}
我无法更改SomeClass
的实现以在未来返回不可修改的列表。编译将正常工作,但如果客户端尝试修改返回的List
,则会在运行时失败。
这就是为什么Guava为集合创建了单独的ImmutableXXX接口吗?
这不是LSP的直接违规吗?还是我完全弄错了?