Предполагая, что вы хотите использовать B в качестве подтипа A в вашей программе:
Да, ваш код явно нарушает LSK.
Почему?
Аргументы должны быть контравариантными.
Что это значит?
Принцип Лискова гарантирует, что ваша программа будет работать без изменений, если ваш подтип B будет заменен базовым типом A.
Или, точнее (Барбара Лисков, 1987):
«Если для каждого объекта o1 типа B существует объект o2 типа A
такой, что для всех программ P, определенных в терминах A, поведение P остается неизменным
когда o1 заменяет o2, тогда B является подтипом A ”.
Например:
class Duck { void fly(int height) {} }
class RedheadDuck : Duck { void fly(long height) {} }
class RubberDuck : Duck { void fly(short height) {} }
class LSPDemo
{
public void Main()
{
Duck p;
p = new Duck();
p.fly(int.MaxValue); // Expected behaviour
p = new RedheadDuck();
p.fly(int.MaxValue); // OK
p = new RubberDuck();
p.fly(int.MaxValue); // Fail
}
}
=> the program behaves unchanged, if the argument is contravariant.
=> e.g. base type <= sub type
=> RubberDuck violates this principle, as it does not allow all values of the base type Duck
В вашем коде тип базового класса A foo будет ожидать значения аргумента -1
Ваш подкласс B foo будет ожидать значения аргумента 0
Если ваша программа заменит подкласс базовым классом, ваша программа не будет работать так, как ожидается для foo в отношении значений <= 0. </p>
EDIT : Несмотря на то, что вы используете тип double для аргументов обоих методов foo, я предполагаю, что вы защищаете свои методы, проверяя значения и их область видимости. Это приведет к описанному сбою, аналогичному примеру.
P.S .: Да, это зависит от контракта, который вы определяете для foo. Предполагая, что вы хотите использовать B как подтип A, это нарушает LSK. В противном случае это просто метод переопределения.