代码之家  ›  专栏  ›  技术社区  ›  AhmadReza Payan

IS-A和Liskov替换原理之间的差异?

  •  7
  • AhmadReza Payan  · 技术社区  · 7 年前

    我只是想知道is-a(UML术语和面向对象编程)和Liskov替换原则(LSP)之间是否有区别?

    实际上,两人都在谈论遗产。那么,实践中的主要区别是什么?

    3 回复  |  直到 7 年前
        1
  •  9
  •   GhostCat    7 年前

    最后,这两个术语描述了相同的“概念”。

    这个 里氏代换原则 告诉你:当使用B类型的某个对象时,类B(基)和C(子)之间的继承关系是合理的。。。可以替换为C类型的对象。

    这意味着:B定义了API和公共契约,而C也必须支持这些属性!

    也是 a B。

    “区别”是:LSP给你 准确的 您可以检查的规则。而IS-A更像是一种“观察”或意图表达。比如:你表达你 C类是A-B。

    换句话说:当您不知道如何正确使用继承时,IS-A不能帮助您编写正确的代码。而LSP清楚地告诉你:

    class Base { int foo(); }
    class Child extends Base { @Override double foo(); }
    

    无效的 . 根据LSP,你只能 拓宽 方法参数,以及

    int iValue = someBase.foo();
    

    int iValue = someChild.foo();
    

    foo() 方法是 加宽 在其结果中。

    最后一个想法是:许多人认为C是B 就像写下来一样 Child extends Base B的有效后代。

    C IS-A B 要求 大于“C延伸B”。要真正有效,LSP必须得到支持!

        2
  •  0
  •   jaco0646    4 年前

    语义更难:它们决定代码对客户端意味着什么。语义通常包括文档等内容。在流行的面向对象编程语言中,编译器无法告诉您代码是否遵循或违反其预期含义。这就是Liskov介入的地方。

        3
  •  -1
  •   Owen Reynolds    6 年前

    Is-A/Has-A是关于是否使用继承的。laserCat是一种激光器,还是应该只有一个激光场?如果以某种方式使用继承,LSP是一个需要注意的特定问题。

    遗传的良好用途是拥有动物a1;指向猫或狗,使用 a1.speed()(*)。LSP表示,猫和狗的速度功能需要使用相同的单位。同样,a1。猫的“设定体重”不能允许负重,但狗会将其更改为0。当您可以调用任何一个函数时,LSP都是关于一致性的。如果你已经知道动物a1,这其实很明显;技巧,这很难。

    语气也不同。Is-a/has-a是给刚起步的人的简单建议。LSP来自一篇30年前的博士论文。它使用的方程是为研究生Com Sci专业设计的。它使用前置和后置条件,这是当时常见的、众所周知的术语。“替换”是一个很好的数学术语,但今天我们只说“一个将指向任何子类的基类”。

    (*)更详细地说:我们有超类动物和亚类猫和狗。动物有一个短截线速度功能,猫和狗都会覆盖它。a1.speed()查找正确的。一个真实的例子是一系列的动物,它们真的能容纳猫和狗。或者一个带有动物输入的函数,期望有一只猫或狗。

    (相同*)基类通常是抽象的-我们永远不会创建动物对象。但是如果我们有一个Toaster超类和一个DeluxeToaster子类,技巧是一样的。任何拿走烤面包机的东西都可以拿走任何“是”烤面包机的东西。