I am solidifying my understanding of the relationship between Liskov Substitutional Principal and Open Close Principal. If anybody could confirm my deductions and answer my questions below that would be great.
I have the following classes. As you can see, B
is derived from A
and it is overriding the DisplayMessage
function in order to alter the behavior.
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");
}
}
Now in my bootstrap program, ShowClassTypeis
expecting an object of Type A
which should helpfully write out what class Type it is. However B
is violating LSP so when it's DisplayMessage
function is called it prints a completely unexpected message and essentially interferes with the intended purpose of 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();
}
}
So my question is, am I right to conclude that ShowClassType
is now violating the Open Close Principal because now that Type B can come in and change the expected function of that method, it is no longer closed for modification (ie. to ensure it maintains it's expected behaviour you would have to alter it so that it first checks to make sure we are only working with an original A object)?
Or, inversely is this just a good example to show that ShowClassType
is closed for modification and that by passing in a derived type (albeit a LSP violating one) we have extended what it is meant to do?
Lastly, is it bad practice to create virtual functions on Base classes if the base class is not abstract? By doing so, are we not just inviting derived classes to violate the Liskov Substitution principal?
Cheers
I'd say it's not ShowClassType
that is violating the Open/Closed Principle.
It's only class B that is violating the Liskov Substitution Principle. A is Open for extension, but closed for modification.
From Wikipedia,
an entity can allow its behaviour to be modified without altering its source code.
It's obvious that the source code of A is not modified. Nor are private members of A being used (which would also be a violation of the Open/Closed principle in my book). B strictly uses the public interface of A, so although the Open/Closed principle is obeyed the Liskov Substitution Principle is violated.
The last question is worth a discussion in and of itself. A related question on SO is here.