Java LSP "derived object can substitute base object"

Java LSP "derived object can substitute base object"

关于 Liskov 替换原则 (LSP),它指出派生 class 的对象可以替换它的基础 classes-object 而不会导致程序无法执行。

如果我的父对象 class 是一个抽象基 class,函数如下:

public abstract class BaseClass {
    public void heal() {
        health++;
    }
}

我可以在派生的 class 中覆盖修复方法吗?它对 LSP 原则仍然有效,例如:

public class ChildClass extends BaseClass {
   @Override public void heal() {
   super.heal();
   super.heal();
}

程序仍将执行,我可以将 ChildClass-Objects 传递给需要 BaseClass-Object 作为参数的方法。然而,这两个 heal() 方法的行为略有不同。

我可以在子classes 中覆盖抽象基 classes 的具体方法而不伤害 LSP 吗?

您可以在派生的 class 方法中实现任何逻辑,只要遵守基础 class 约定即可。合同是由 classes 及其方法提供的保证,通常在文档中进行描述。一些语言提供更形式化的合同规范,例如编译时断言。方法签名也可以被视为合同的一部分。

如果您的 heal 方法被记录为 "Add one point to the object's health",那么使用您的 BaseClass 的其他 class 仅依赖于添加一点。在这种情况下,覆盖 heal 以向健康添加任何其他数量会违反合同并违反 LSP。

相反,如果 heal 是 "Adds some points to the object's health" 的方法,那么其他 class 不允许对实际添加的数量提出任何建议 -- 唯一的他们可以依赖的是,例如调用此方法后的 health 不小于调用 heal 之前的 health 。在这种情况下,您的覆盖不会违反 LSP,也不会破坏程序。