是否有一个孩子实施了一个界面而另一个没有违反Liskov替换原则?

时间:2014-01-13 13:48:25

标签: c# design-patterns solid-principles single-responsibility-principle design-principles

我最近一直在考虑Liskov替换原则以及它与我当前任务的关系。我有一个包含菜单的主表单;在这个主要表单中,我将一个特定的表单作为MDI子对接。此特定表单可能包含也可能不包含菜单。如果是,我想将它与主菜单合并。所以情况是这样的:

public class MainForm
{
    public void Dock(SpecificBaseForm childForm)
    {
        this.Dock(childForm);
        if (childForm is IHaveMenu)
        {
            this.Menu.Merge(childForm as IHaveMenu).Menu;
        }
    }
 }

public interface IHaveMenu
{
   Menu Menu {get;}
}

public abstract class SpecificBaseForm{}

public class SpecificFormFoo : SpecificBaseForm {}

public class SpecificFormBar: SpecificBaseForm,IHaveMenu
{
    public Menu Menu{get {return this.Menu;}}
}

现在这两个孩子并不是“完全”可互换的:一个有菜单;另一个没有。这是在C#中误用is / as contruct吗?如果这不正确,那么干净的解决方案是什么?

2 个答案:

答案 0 :(得分:5)

不,这不违反Liskov substitution principle。特定子类是否实现不同的接口并不重要,只要它们可以用来代替基类。

还要记住,LSP是关于类的行为,不是关于方法的签名,还是它们是否实现了额外的接口。

答案 1 :(得分:3)

Liskov substitution principle表示基类必须能够被更多派生的子类型替换。子类不需要能够互相替换,只要每个子类可以替换基类而不破坏程序或者导致它不能按需运行。因此,您描述的实例不会违反LSP。