I am looking for few examples of class extension without Lyskov Substitution Principle violation, where class being extended is not a template/abstract/skeleton class, and extending class isn't just a decorator.
+1
A:
public class Question
{
public string Question { get; set; }
public string Author { get; set; }
public virtual bool IsRelevant { get { return true; } }
}
public class OverlyVagueQuestion : Question
{
public override bool IsRelevant { get { return false; } }
}
Justin Niessner
2010-10-05 14:59:59
`Question` class is abstract. There is no implementation for IsRelevant, I bet as soon as you provide IsRelevant implementation - it'll break LSP in OverlyVagueQuestion.
2010-10-05 15:02:03
@user93422 - `Question` is a class, therefore an implementation (it is not an interface and is not marked as abstract).
Oded
2010-10-05 15:03:23
@Odded, now it is.
2010-10-05 15:05:49
@Justin: OverlyVagueQuestion changes behavior of IsRelevant method. It is a LSP violation.Here is a test that will be broken `public void IsRelevantShouldReturnTrue() { Assert.IsTrue(new Question().IsRelevant); }`
2010-10-05 15:06:28
@user93422 - Changing behavior doesn't necessarily violate LSP unless preconditions are strengthened or postconditions are weakened. In this case, calling IsRelevant on the child does not modify any state of the parent no neither of those two requirements are violated.
Justin Niessner
2010-10-05 15:12:19
I would agree with you, in practice. But "If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2, then S is a subtype of T." So changing behavior **is** an LSP violation, academically speaking. Can you think of an example where behavior doesn't change?
2010-10-05 15:24:23
It's the *Substitutability* principle, not the *Totally-equivalent-for-all-imaginable-purposes* principle. There are examples in the wikipedia article if you want them.
Nathan Hughes
2010-10-05 17:28:37