Click here to Skip to main content
15,887,214 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Is Liskov Substitution works with out abstract class?

For ex:
public class SumCalculator
{
    protected readonly int[] _numbers;
 
    public SumCalculator(int[] numbers)
    {
        _numbers = numbers;
    }
 
    public virtual int Calculate() => _numbers.Sum();
}

public class EvenNumbersSumCalculator: SumCalculator
{
    public EvenNumbersSumCalculator(int[] numbers)
        :base(numbers)
    {
    }
 
    public override int Calculate() => _numbers.Where(x => x % 2 == 0).Sum();
}

When i use following statement, i get expected answer and logic is perfect.

SumCalculator evenSum = new EvenNumbersSumCalculator(numbers);
Console.WriteLine($"The sum of all the even numbers: {evenSum.Calculate()}");

But LSP is not followed here because when child class is substituted, behaviour got  changed.

Then i created an abstarct class 
public abstract class Calculator
{
    protected readonly int[] _numbers;
 
    public Calculator(int[] numbers)
    {
        _numbers = numbers;
    }
 
    public abstract int Calculate();
}
Now my both classes will implement from abstract Calculator class and i got expected result also. 

But my question is when we use just base class and child class, always it will changes behaviour and it will be against LSP. Is this correct? If not can somebody provide me some more details. 

Please dont send me links because i have seen manylinks and could not get answer.


What I have tried:

For ex:
public class SumCalculator
{
    protected readonly int[] _numbers;
 
    public SumCalculator(int[] numbers)
    {
        _numbers = numbers;
    }
 
    public virtual int Calculate() => _numbers.Sum();
}

public class EvenNumbersSumCalculator: SumCalculator
{
    public EvenNumbersSumCalculator(int[] numbers)
        :base(numbers)
    {
    }
 
    public override int Calculate() => _numbers.Where(x => x % 2 == 0).Sum();
}
Posted
Updated 30-Jul-20 6:15am

1 solution

You can use an interface rather than an abstract class, however I don't think LSP says that the outcome has to be the same, simply that the code doesn't break. If the outcome of the two objects are the same there is little point in having two of them, or changing one for another.
 
Share this answer
 
Comments
BillWoodruff 31-Jul-20 2:15am    
+5
code4Better 31-Jul-20 4:08am    
Thank you for the response @F-ES Sitecore. The Liskov Substitution Principle says that "the object of a derived class should be able to replace an object of the base class without bringing any errors in the system or modifying the behavior of the base class". When it says with out modifying the behavior, virtual override cannot be used with out abstract or interface. This means to adapt LSP, class should have an interface or abstract as base class. This was my confusion.
F-ES Sitecore 31-Jul-20 5:50am    
It certainly makes it easier in some cases if you use a shared abstract class or interface, but I don't think it is strictly necessary. You can have a base class of Animal with a property "NumberOfLegs" and replace Animal with Cat and your NumberOfLegs property can continue to function even though you are not using abstract classes or interfaces.
code4Better 1-Aug-20 7:28am    
Yes, we can. Thank you!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900