下面是来自在线教程的代码(https://code-maze.com/liskov-substitution-principle/):
// version 1
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();
}
那么我们可以这样做:
class Program
{
static void Main(string[] args)
{
var numbers = new int[] { 5, 7, 9, 8, 1, 6, 4 };
SumCalculator sum = new SumCalculator(numbers);
Console.WriteLine($"The sum of all the numbers: {sum.Calculate()}");
Console.WriteLine();
SumCalculator evenSum = new EvenNumbersSumCalculator(numbers);
Console.WriteLine($"The sum of all the even numbers: {evenSum.Calculate()}");
}
}
所以我们可以把子实例new EvenNumbersSumCalculator(numbers)
(SumCalculator evenSum
但是教程说版本 1 不符合 Liskov 原则,我们需要这样做:
// version 2
public abstract class Calculator
{
protected readonly int[] _numbers;
public Calculator(int[] numbers)
{
_numbers = numbers;
}
public abstract int Calculate();
}
public class SumCalculator : Calculator
{
public SumCalculator(int[] numbers)
:base(numbers)
{
}
public override int Calculate() => _numbers.Sum();
}
public class EvenNumbersSumCalculator: Calculator
{
public EvenNumbersSumCalculator(int[] numbers)
:base(numbers)
{
}
public override int Calculate() => _numbers.Where(x => x % 2 == 0).Sum();
}
class Program
{
static void Main(string[] args)
{
var numbers = new int[] { 5, 7, 9, 8, 1, 6, 4 };
Calculator sum = new SumCalculator(numbers);
Console.WriteLine($"The sum of all the numbers: {sum.Calculate()}");
Console.WriteLine();
Calculator evenSum = new EvenNumbersSumCalculator(numbers);
Console.WriteLine($"The sum of all the even numbers: {evenSum.Calculate()}");
}
}
我不明白为什么版本 1 不符合 Liskov 原则?