Принцип подстановки Лискова - пример переопределения метода - PullRequest
5 голосов
/ 21 декабря 2011

Допустим, у нас есть действительно тривиальные классы:

class A
{
    virtual int Function(int number)
    {
      return number;
    }
}

class B : A
{
    override int Function(int number)
    {
        return number + 1;
    }
}

class UseExample
{
    void Foo(A obj)
    {
        A.Function(1);
    }
}

Будет ли этот пример нарушением LSP ?. Если да, не могли бы вы привести пример, который не нарушает принцип и использует другую реализацию?

А как насчет этого:

class B : A
{
    int variable;

    override int Function(int number)
    {
        return number + variable;
    }
}

Насколько я понял, использование переменной "переменная" вызывает более сильное предварительное условие и, следовательно, нарушает LSP. Но я не совсем уверен, как следовать LSP при использовании полиморфизма.

Ответы [ 2 ]

2 голосов
/ 21 декабря 2011

Это верно, в обоих случаях это не нарушает принцип.B можно заменить на A. Он просто имеет другую функциональность.

простой способ разорвать контракт состоит в том, чтобы вызвать исключение в переопределении Bs, если число == 23 или что-то еще:)

0 голосов
/ 05 февраля 2014

Из моего понимания я бы сказал, что оба ваших примера нарушают LSP, поскольку подкласс не может быть заменен его суперклассом.Обратите внимание на следующее:

class UseExample {
    void Foo(A& obj, int number) {
        int retNumber = obj.Function(number);
        assert(retNumber==number);
    }
}

Если вы передадите ссылку на объект B в Foo, утверждение не будет выполнено.B.Функция меняет постусловие А.Функции.Код клиента Foo не должен знать о возможных подтипах, которые могут нарушить их код.

...