I would like to refer to the example that was used earlier in https://stackoverflow.com/a/4129/64 with the duck and electric duck:
public interface IDuck { void Swim(); } public class Duck : IDuck { public void Swim() {
The original violation for the LSP would look like this:
void MakeDuckSwim(IDuck duck) { if (duck is ElectricDuck) ((ElectricDuck)duck).TurnOn(); duck.Swim(); }
One of the author’s decisions was to incorporate logic into the electric duck duck method:
public class ElectricDuck : IDuck { public void Swim() { if (!IsTurnedOn) TurnOn();
I came across other scenarios where an advanced interface can be created that supports some initialization:
public interface IInitializeRequired { public void Init(); }
The electric weft can then be expanded using this interface:
public class ElectricDuck : IDuck, IInitializeRequired { public void Swim() { if (!IsTurnedOn) return;
EDIT: The reason for the extended interface is based on the fact that the author says that automatic inclusion in the swimming method may have other undesirable results.
Then, instead of checking and dropping a specific type, you can look for an advanced interface:
void MakeDuckSwim2(IDuck duck) { var init = duck as IInitializeRequired; if (init != null) { init.Init(); } duck.Swim(); }
The fact that I made the initialization concept more abstract, and then created an advanced interface called IElectricDuck with the TurnOn () method, can make it do the right thing, but the whole Init concept can only exist because of the electric duck.
Is this the best way / solution or is it just breaking the LSP in disguise.
thanks