oop - Java LSP "derived object can substitute base object"

标签 oop liskov-substitution-principle

关于里氏替换原则(LSP),它指出派生类的对象可以替换它的基类对象,而不会导致程序无法执行。

如果我的父类是一个具有函数的抽象基类怎么办:

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

我可以重写派生类中的修复方法吗,并且它对 LSP 原则仍然有效,例如:

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

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

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

最佳答案

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

如果您的 heal 方法被记录为“为对象的健康添加一个点”,那么使用您的 BaseClass 的其他类仅依赖于添加一个点。在这种情况下,重写 heal 来添加任何其他数量的生命值会破坏契约并违反 LSP。

相反,如果 heal 是一个“为对象的健康状况添加一些点”的方法,那么其他类不允许对实际添加的数量提出任何建议——唯一的事情例如,他们可以依赖的是,调用此方法后的 health 不小于调用 heal 之前的 health。在这种情况下,您的覆盖不会违反 LSP 并且不会破坏程序。

关于oop - Java LSP "derived object can substitute base object",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34705472/

相关文章:

java - 如何创建启动 Activity 的方法?

oop - 发送自己的对象 - 好主意吗?

java - 深层对象图 hibernate

javascript - 按属性值对对象排序

python - 重载(而不是重写)是否违反了里氏替换原则?

java - 组合优于继承和紧耦合

java - 抽象属性是否违反 Liskov 替换原则?

oop - 任何人都可以提供使用车辆的 Liskov 替换原则 (LSP) 的示例吗?

python - Mypy 在 __init__ 覆盖中接受不兼容的类型

java - 在这种情况下我可以违反LSP(里氏替换)吗?