Не нарушают ли абстрактные свойства принцип подстановки Лискова? - PullRequest
8 голосов
/ 06 июня 2011

Предположим, у меня есть абстрактный класс, например:

public abstract class Pet {
    private final String name;
    public Pet(String name) { 
        this.name = name 
    };

    public abstract boolean getsSpecialTreatment();
}

public final class Dog extends Pet {
    @Override public boolean getsSpecialTreatment() { return true; }
}

public final class Cat extends Pet {
    @Override public boolean getsSpecialTreatment() { return false; }
}

Моя программа будет обрабатывать Pet с по-разному в зависимости от того, установлен ли флаг специальной обработки.Мой вопрос заключается в том, считается ли это нарушением принципа подстановки Лискова, который гласит:

[...] в компьютерной программе, если S является подтипом T, тогда объекты типа T могут бытьзаменяется объектами типа S [...] без изменения каких-либо желательных свойств этой программы (корректность, выполненная задача и т. д.).

Ответы [ 4 ]

6 голосов
/ 06 июня 2011

В этом случае пользователи этих классов, вероятно, напишут:

...
if (pet.getsSpecialTreatment()) {
    // special treatment
    ...
} else {
    // normal treatment
    ...
}
...

Этот код будет работать в обоих случаях, поэтому вы не будете нарушать LSP. Однако, если у вас было

public class UnknownAnimal extends Pet {
    @Override public boolean getsSpecialTreatment() {
        throw new UnsupportedOperationException("Unknown species"); 
    }
}

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

4 голосов
/ 06 июня 2011

Нет. Любое использование метода в программе будет основывать последующие решения на возвращаемом значении, как и любой другой метод. По самой природе существования метода ни одна программа не должна делать предположений относительно его результатов. Следовательно, изменение значения, возвращаемого этим методом, не должно изменять свойства программы.

1 голос
/ 06 июня 2011

Во-первых, решительное возражение против вашей дискриминации кошек!

Теперь, когда программисты используют так называемый «принцип подстановки Лискова», они на самом деле не говорят об этом в его академическом смысле. Мы должны использовать это в неформальном, вульгарном, ублюдочном смысле.

Какой в ​​этом смысл? Я нахожу это не более чем требованием, чтобы подкласс соответствовал контракту, установленному суперклассом. Так что это действительно неинтересно. Люди называют эту фразу просто фанаткой.

0 голосов
/ 11 октября 2018

Зависит от договора.То есть код, использующий ваши классы, должен иметь согласованное поведение, независимо от того, какой тип вашего типа он использует.

Если в контракте, указанном «getSpecialTreatment», всегда возвращается значение true, это будет нарушением в вашем производном классе.

Если в контракте указано, что getSpecialTreatment возвращает логическое значение, определяющее blabla., Тогда вы не нарушаете LSP.

Вы можете нарушить LSP, если вы ввели дополнительное ограничение, которого нет в базекласс.

...