// A 'good example' on Liskov substitution is simply to not allow our sub-classes to differ in the meaning of their
        // implementations. I.e. no explicit paths for certain sub-types, no strenghtening of conditions etc.
        // If a need to break away from limitations of the originals class arises,
        // we can add the required functionality to that original class.

        // By introducing an abstract base-class, which takes into consideration the diverse implementations,
        // we can ensure sub-class compatibility. Given additional requirements - for example, we only need to modify the base-class,
        // single point of maintainability.
        public static void Main()
        {
            VoltageSensor voltageSensor = new VoltageSensor();

            voltageSensor.ReadCurrentSensorVoltage();
            voltageSensor.RaiseAlarmIfVoltageBelowThreshold();
        }
Example #2
0
        // The Liskov Substitution Principle states that an object with a certain interface can be replaced by a different object that implements that same interface while retaining all the correctness of the original program. That means that not only does the interface have to have exactly the same types, but the behavior has to remain correct as well.

        // A VoltageSensor-class reads a sensor-voltage and raises an alarm if the voltage dips below a given threshold. This works well for a Standard-voltage alarm, but a newly introduced NewVoltageAlarm() implementation introduces different requirements and thus breaks the Liskov substitution principle.
        public static void Main()
        {
            VoltageSensor voltageSensor = new VoltageSensor();

            voltageSensor.SetVoltageAlarm(new StandardVoltageAlarm(3.3d));
            voltageSensor.ReadCurrentSensorVoltage();
            voltageSensor.RaiseAlarmIfVoltageBelowMinimum();
        }