Last updated
Last updated
Барбара Лисков, дефинира принципа през 1988 г., като:
Ако за всеки обект o1 от тип S има обект o2 от тип T такъв, че за всички програми P, дефинирани по отношение на T, поведението на P е непроменено, когато o1 е заместен за o2 тогава S е подтип на T.
Или както го обобщава Робърт С. Мартин:
Подтиповете трябва да бъдат заместващи на базовите си типове.
По отношение на LSP методите, които използват извиккване на базови класове, трябва да могат да използват обекти от производния клас, без да го знаят. С прости думи производните класове трябва да бъдат заместващи на базовия клас, за да е приложен принципа на LSP.
Нека вземем пример за правоъгълници и квадратчета. Има тенденция да се установи връзката, по този начин, можете да кажете, че квадрат е правоъгълник. Възниква обаче проблем (оттук — нарушение на LSP), което се доказва със следния пример.
Кодът на метода за пресмятане има Правоъгълник като аргумент. Що се отнася до принципа, функциите, които използват препратки към базовите класове, трябва да могат да използват обекти от производен клас, без да го знаят. По този начин, в примера, метода calculateArea, който използва препратката на "Правоъгълник," трябва да бъде в състояние да използва обектите от производен клас, като Square, и да изпълни изискването, породено от Правоъгълник определение.
Погледнете calculateArea методa за който трябва да отбележи, че според определението за Правоъгълник, следното трябва винаги да бъде вярно:
Двете дължини трябва да са винаги равни, setLength.
Двете ширини трябва да са винаги равни, setBreadth.
Площта трябва винаги да е равна на произведението от дължина и ширина.
В този случай се опитваме да установим връзка между Square и Rectangle такава, че да наричаме "Square е Rectangle" кода би започнал да се държи непредвидено, ако се подаде екземпляр на Square. Грешка в твърдението ще бъде хвърлена в случай на проверка за "Площ" и проверка за "Ширина", въпреки че програмата ще прекрати, тъй като грешката в твърдението е хвърлена поради неуспеха на проверката на Площа.
Като се има предвид примера, какъв е проблемът с отношенията Квадрат-Правоъгълник?
Класът Square не се нуждае от методи като setBreadth или setLength, тъй като страните на квадрат са равни. Представете си за стотици хиляди обекти, Square че трябва да се сетват две повтарящи се стойности вместо една.
Класът LSPDemo ще трябва да знае подробностите за производните класове Rectangle (като Square), за да изпълнява по подходящ начин, и да се избегне грешка. Ще има нужда от промяната в съществуващия код, за да се грижи за производния клас, на първо място нарушава принципа на еденичната отговорност.
Трябва да се следват някои от характеристиките за качество на кода, които са представени от принципа на Лисков.
Само когато производните типове са напълно заместващи за базовите си типове, функциите, които използват тези базови типове, могат да се използват повторно безнаказано, а производните типове могат да бъдат променяни безнаказано.
Използвайки този принцип, методите на класовете декларират предварителни условия и постустановени условия. Предварителните условия трябва да са верни, за да може методът да се изпълни. След завършване методът гарантира, че след условието ще бъде вярно.
Пройзводните класове трябва да хвърлят изключения за свойствата който не могат да обработят от базовите класове
Нека да разгледаме пример: