当前位置: 首页 > 知识库问答 >
问题:

Liskov代换原理与虚方法

姚臻
2023-03-14

我在派生类中重写了带有附加先决条件的虚拟函数。这是快照-

class Process
{
    protected virtual void ValidateDates()
    {
        if (Entity.StartDate.Date > Entity.EndDate.Date)
        {
            AddFailure("Start date cannot be later than the End date");
        }
    }
}

class InitialProcess : Process
{
    protected override void ValidateDates()
    {
        base.ValidateDates();
        if (IsImmediateProcess)
        {
            if (Entity.StartDate.Date > CurrentDateTime.Date)
            {
                AddFailure("Start date cannot be later than the current date");
            }
        }
    }
}

如果我理解正确的话,这里的代码通过附加一个先决条件打破了Liskov替换-IsImmediateProcess和其他日期检查。对吗?或者一个被重写的函数调用一个基函数,然后向它添加自己的行为,这样可以吗?

我不能将重写方法中由初始过程类型引入的条件移动到基本类型,因为它是特定于初始过程的。

在这种情况下,如果派生类重写行为并希望在不违反Liskov原则的情况下替换自己的行为,那么实现重写行为的最佳方法是什么?

共有2个答案

周奇
2023-03-14

正如亨克·霍尔特曼所说,它没有违反LSP。就是强化后置条件,不要弱化前置条件,这就可以了。

因此,它执行基类通过调用执行的操作:

base.ValidateDates();

并添加一些后置条件(加强了后置条件):

if (IsImmediateProcess)

恕我直言

袁宜
2023-03-14

假设你指的是类初始过程:过程

这完全符合利斯科夫原理。

这两个类具有相同的接口,但具有不同的(扩展)行为。派生类没有不同的前置条件,它有不同的验证规则。这是很好的,不会打破任何东西。

 类似资料:
  • 存在无法写入或查找的流派生类这一事实是否违反了Liskov替换原则? 例如,无法查找NetworkStream,如果调用方法,它将抛出。 还是因为存在标志就可以了? 考虑到众所周知的继承自的例子...将标志和添加到是否可以解决问题? 这难道不是打开了通过添加旗帜来解决问题的大门吗?

  • 我试图理解Liskov替换原理,我有以下代码: 我不确定这是否违反了它。原理是,如果你有一个类S的对象,那么你可以用另一个类T的对象来代替它,其中S是T的一个子类。但是,如果我写了 这当然会产生编译错误,因为Vehicle类没有openDoor()方法。但这意味着我不能用它们的父类Vehicle替换VehicleWithDoors对象,这似乎违反了原则。那么这个代码是否违反了它?我需要一个好的解释

  • 在创建我的班级结构时,我努力坚持利斯科夫替代原则。我想在Day类中存储一组日历项。需要有几种不同类型的日历项,例如: 任命项目 备注项目 轮换项目 它们都共享一些抽象基类CalendarItem中的常见功能: 但例如RotaItem有一些额外的功能: 其他类也添加了自己的逻辑等。 我有一组CalendarBaseItem用于我的日课: 但在回顾这一点时,我可以看到我正在打破LSP原则,因为我必须检

  • Liskov替代原理(LSP)说: 先决条件不能在子类型中得到加强。 在C#中,我可能违反以下整个原则: 但是,如果是一种方法,会发生什么呢 现在是无合同的。或者它的合同就是一切允许的。 那么,前提条件是否违反了Liskov替代原则?

  • 我试图通过反复阅读维基百科条目来确定我对上述原则的理解。 撇开仍然让我悲伤的协变和逆变的概念不谈,wikipedia还提到超类型的不变量必须保留在子类型和历史约束或历史规则中。基于最后两个概念,我提出了一个小例子: 所以我的问题是:基于上述两个概念,我用这个例子是否违反了原则?若否,原因为何? 事先非常感谢。