我正在巩固对Liskov Substitutional Principal和Open Close Principal之间关系的理解。如果有人能够确认我的扣除并在下面回答我的问题,那就太棒了。
我有以下课程。如您所见,B
派生自A
,它会覆盖DisplayMessage
函数以改变行为。
public class A
{
private readonly string _message;
public A(string message)
{
_message = message;
}
public virtual void DisplayMessage()
{
Console.WriteLine(_message);
}
}
public class B : A
{
public B(string message) : base(message){}
public override void DisplayMessage()
{
Console.WriteLine("I'm overwriting the expected behavior of A::DisplayMessage() and violating LSP >:-D");
}
}
现在在我的引导程序中,ShowClassTypeis
期望类型A
的对象应该有助于写出它是什么类。但是B
违反了LSP,因此当调用DisplayMessage
函数时,它会打印出一个完全意外的消息,并且基本上会干扰ShowClassType
的预期目的。
class Program
{
static void Main(string[] args)
{
A a = new A("I am A");
B b = new B("I am B");
DoStuff(b);
Console.ReadLine();
}
private static void ShowClassType(A model)
{
Console.WriteLine("What Class are you??");
model.DisplayMessage();
}
}
所以我的问题是,我是否正确地断定ShowClassType
现在违反了Open Close Principal,因为既然Type B可以进入并改变该方法的预期函数,它就不再关闭以进行修改(即确保它保持预期的行为,你必须改变它,以便它首先检查以确保我们只使用原始的A对象)?
或者,相反,这只是一个很好的例子,表明ShowClassType
已关闭进行修改,并且通过传入派生类型(尽管LSP违反了一个),我们已经扩展了它的意图吗? / p>
最后,如果基类不是抽象的,那么在Base类上创建虚函数是不好的做法吗?通过这样做,我们不只是邀请衍生类违反Liskov替换校长吗?
干杯
答案 0 :(得分:0)
我认为违反开放/封闭原则并非ShowClassType
。
只有B级违反Liskov替代原则。 A是Open for extension,但已关闭以进行修改。
来自Wikipedia,
实体可以允许修改其行为而不改变其源代码。
很明显,A的源代码没有被修改。也没有使用A的私人成员(这也违反了我书中的开放/封闭原则)。 B严格使用A的公共接口,因此虽然遵守了开放/封闭原则,但违反了Liskov替换原则。
最后一个问题值得讨论。关于SO的相关question就在这里。
答案 1 :(得分:0)
我认为在这个使用环境中不违反LSP而不是OCP。
对于我的看法,ShowClassType不违反OCP: 1.功能不能破坏OCP,只有类架构才能做到这一点。 2.您可以从A中向派生类添加新行为 - 因此它不会破坏OCP
LSP怎么样?你的理由 - 用户不期望得到这条消息?但他收到了一些消息!如果函数重写返回一些消息,我认为在你的代码的这个上下文中是可以的。 如果函数,添加两个数字是覆盖,1 + 1返回678,这对我来说是不可预期的并且是坏的。但是,如果对于来自火星星球的物理科学家来说,它可以是一个很好的答案。
不要在没有所有背景的情况下分析问题!你必须全面了解问题。而且,当然