这违反了利斯科夫替代原则吗

本文关键字:原则 | 更新日期: 2023-09-27 18:29:08

我的自定义按钮实际上是一个按钮,那么它是否违反了LSP?

class ConditionalButton : Button
{
    protected override void OnClick(EventArgs e)
    {
        if (Condition())
            base.OnClick(e);
    }
    private bool Condition()
    {
        //return true or false
    }
}

这违反了利斯科夫替代原则吗

这是子类型中先决条件的增强。明显违反LSP。

按钮显示:

只要按钮被启用,点击做一些工作

条件按钮显示:

只要按钮被启用并且Condition()为true,点击完成一些工作

在我看来,这确实违反了LSP。请参阅Object Mentor文章中对Liskov替代原理的简化定义:

"使用基类的指针或引用的函数必须能够在不知情的情况下使用派生类的对象。"

从这个角度来看,我们可以将ConditionalButton用作Button,这似乎是可以的。但是:

为了使LSP保持不变,并遵循开闭原理,所有导数必须符合客户端对其使用的基类的期望行为

并且可以肯定的是,客户端期望在点击按钮之后,OnClick将被执行。

此外,来自同一篇文章:

当[在派生函数中]重新定义例程时,只能替换它一个较弱的先决条件,一个较强的后决条件。

在我看来,ConditionalButton违反了当前形式的LSP,因为Condition允许点击按钮,而与按钮相关的逻辑将不会执行。如果Condition与enabled/disabled标志相关,则不会违反LSP。