我最近一直在考虑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吗?如果这不正确,那么干净的解决方案是什么?
答案 0 :(得分:5)
不,这不违反Liskov substitution principle。特定子类是否实现不同的接口并不重要,只要它们可以用来代替基类。
还要记住,LSP是关于类的行为,不是关于方法的签名,还是它们是否实现了额外的接口。
答案 1 :(得分:3)
Liskov substitution principle表示基类必须能够被更多派生的子类型替换。子类不需要能够互相替换,只要每个子类可以替换基类而不破坏程序或者导致它不能按需运行。因此,您描述的实例不会违反LSP。