{"id":255,"date":"2025-10-13T21:08:51","date_gmt":"2025-10-13T19:08:51","guid":{"rendered":"https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/?p=255"},"modified":"2025-10-14T09:00:10","modified_gmt":"2025-10-14T07:00:10","slug":"liskov-substitution-principle","status":"publish","type":"post","link":"https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/?p=255","title":{"rendered":"Liskov Substitution Principle"},"content":{"rendered":"\n<hr class=\"wp-block-separator has-css-opacity is-style-default\"\/>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity is-style-default\"\/>\n\n\n\n<div class=\"wp-block-media-text alignwide has-media-on-the-right is-stacked-on-mobile is-vertically-aligned-center has-background\" style=\"background-color:#f1f5c7\"><div class=\"wp-block-media-text__content\">\n<div class=\"wp-block-group is-layout-flow wp-block-group-is-layout-flow\" style=\"padding-top:2em;padding-right:2em;padding-bottom:2em;padding-left:2em\">\n<p style=\"font-size:36px;line-height:1.2\"><strong>Definicja<\/strong><\/p>\n\n\n\n<p class=\"has-extra-small-font-size\">Zasada podstawienia Liskov (ang. <em>Liskov Substitution Principle<\/em>, LSP) m\u00f3wi, \u017ce <strong>obiekty klasy pochodnej powinny m\u00f3c zast\u0119powa\u0107 obiekty klasy bazowej bez zmiany poprawno\u015bci dzia\u0142ania programu<\/strong>.<br>Innymi s\u0142owy \u2013 je\u015bli klasa <code>B<\/code> dziedziczy po klasie <code>A<\/code>, to obiekt <code>B<\/code> powinien zachowywa\u0107 si\u0119 tak, by program, kt\u00f3ry dzia\u0142a z <code>A<\/code>, dzia\u0142a\u0142 poprawnie tak\u017ce z <code>B<\/code>.<\/p>\n<\/div>\n<\/div><figure class=\"wp-block-media-text__media\"><img data-opt-id=807734801  fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"683\" src=\"https:\/\/mlb55nihrfbl.i.optimole.com\/w:1024\/h:683\/q:mauto\/ig:avif\/http:\/\/ewelina-beben.profesjonalnyprogramista.pl\/wp-content\/uploads\/2025\/10\/Businessmans-hand-holding-question-mark.jpg\" alt=\"\" class=\"wp-image-240 size-full\" srcset=\"https:\/\/mlb55nihrfbl.i.optimole.com\/w:1024\/h:683\/q:mauto\/ig:avif\/https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/wp-content\/uploads\/2025\/10\/Businessmans-hand-holding-question-mark-scaled.jpg 1024w, https:\/\/mlb55nihrfbl.i.optimole.com\/w:300\/h:200\/q:mauto\/ig:avif\/https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/wp-content\/uploads\/2025\/10\/Businessmans-hand-holding-question-mark-scaled.jpg 300w, https:\/\/mlb55nihrfbl.i.optimole.com\/w:768\/h:512\/q:mauto\/ig:avif\/https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/wp-content\/uploads\/2025\/10\/Businessmans-hand-holding-question-mark-scaled.jpg 768w, https:\/\/mlb55nihrfbl.i.optimole.com\/w:1536\/h:1024\/q:mauto\/ig:avif\/https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/wp-content\/uploads\/2025\/10\/Businessmans-hand-holding-question-mark-scaled.jpg 1536w, https:\/\/mlb55nihrfbl.i.optimole.com\/w:1620\/h:1080\/q:mauto\/ig:avif\/https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/wp-content\/uploads\/2025\/10\/Businessmans-hand-holding-question-mark-scaled.jpg 2048w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" \/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-media-text alignwide is-stacked-on-mobile is-vertically-aligned-center has-background\" style=\"background-color:#fffdea\"><figure class=\"wp-block-media-text__media\"><img data-opt-id=456970336  fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"1024\" src=\"https:\/\/mlb55nihrfbl.i.optimole.com\/w:1024\/h:1024\/q:mauto\/ig:avif\/https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/wp-content\/uploads\/2025\/10\/d53fef4b-8ff4-4e94-a781-2c7373c4e1a1.jpg\" alt=\"\" class=\"wp-image-257 size-full\" srcset=\"https:\/\/mlb55nihrfbl.i.optimole.com\/w:1024\/h:1024\/q:mauto\/ig:avif\/https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/wp-content\/uploads\/2025\/10\/d53fef4b-8ff4-4e94-a781-2c7373c4e1a1.jpg 1024w, https:\/\/mlb55nihrfbl.i.optimole.com\/w:300\/h:300\/q:mauto\/ig:avif\/https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/wp-content\/uploads\/2025\/10\/d53fef4b-8ff4-4e94-a781-2c7373c4e1a1.jpg 300w, https:\/\/mlb55nihrfbl.i.optimole.com\/w:150\/h:150\/q:mauto\/ig:avif\/https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/wp-content\/uploads\/2025\/10\/d53fef4b-8ff4-4e94-a781-2c7373c4e1a1.jpg 150w, https:\/\/mlb55nihrfbl.i.optimole.com\/w:768\/h:768\/q:mauto\/ig:avif\/https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/wp-content\/uploads\/2025\/10\/d53fef4b-8ff4-4e94-a781-2c7373c4e1a1.jpg 768w, https:\/\/mlb55nihrfbl.i.optimole.com\/w:1080\/h:1080\/q:mauto\/ig:avif\/https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/wp-content\/uploads\/2025\/10\/d53fef4b-8ff4-4e94-a781-2c7373c4e1a1.jpg 1536w, https:\/\/mlb55nihrfbl.i.optimole.com\/w:1080\/h:1080\/q:mauto\/ig:avif\/https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/wp-content\/uploads\/2025\/10\/d53fef4b-8ff4-4e94-a781-2c7373c4e1a1.jpg 2048w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" \/><\/figure><div class=\"wp-block-media-text__content\">\n<div class=\"wp-block-group is-layout-flow wp-block-group-is-layout-flow\" style=\"padding-top:2em;padding-right:2em;padding-bottom:2em;padding-left:2em\">\n<p style=\"font-size:36px;line-height:1.2\"><strong>Przyk\u0142ad z \u017cycia<\/strong><\/p>\n\n\n\n<p class=\"has-extra-small-font-size\">Wyobra\u017amy sobie system zarz\u0105dzania prefabrykacj\u0105, kt\u00f3ry obs\u0142uguje r\u00f3\u017cne typy element\u00f3w \u2013 <strong>belki, p\u0142yty i s\u0142upy<\/strong>.<br>Wszystkie maj\u0105 wsp\u00f3lne cechy: wymiary, mas\u0119 i funkcj\u0119 <em>transportu na plac budowy<\/em>.<\/p>\n\n\n\n<p>Jednak kto\u015b tworzy klas\u0119 \u201eElementTymczasowy\u201d, kt\u00f3ra dziedziczy po \u201ePrefabElement\u201d, ale <strong>nie mo\u017ce by\u0107 transportowana<\/strong>, bo to tylko element testowy (np. pr\u00f3bka).<br>Je\u015bli system spr\u00f3buje przetransportowa\u0107 ka\u017cdy element w taki sam spos\u00f3b, u\u017cywaj\u0105c tej klasy, to program si\u0119 \u201ewywr\u00f3ci\u201d \u2014 naruszy zasad\u0119 Liskov.<\/p>\n\n\n\n<p class=\"has-extra-small-font-size\">Ka\u017cdy obiekt klasy pochodnej powinien <strong>zachowywa\u0107 si\u0119 sp\u00f3jnie z oczekiwaniami klasy bazowej<\/strong>.<\/p>\n<\/div>\n<\/div><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"font-size:38px;line-height:1.4\"><strong>Przyk\u0142ady przed i po zastosowaniu zasady<\/strong><\/h2>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p><strong>PRZED<\/strong><\/p>\n\n\n\n<p style=\"font-size:18px\">Poni\u017cszy przyk\u0142ad <strong>\u0142amie zasad\u0119 Liskov<\/strong>, bo klasa <code>TemporaryElement<\/code> zmienia zachowanie metody <code>transport<\/code>, w spos\u00f3b sprzeczny z klas\u0105 bazow\u0105.<\/p>\n\n\n\n<p style=\"font-size:18px\">Kod oczekuje, \u017ce ka\u017cda instancja <code>PrefabElement<\/code> ma metod\u0119 <code>transport<\/code>, kt\u00f3ra dzia\u0142a poprawnie.<br>Jednak <code>TemporaryElement<\/code> zmienia jej zachowanie \u2014 powoduje wyj\u0105tek.<br>To <strong>\u0142amie zasad\u0119 podstawienia Liskov<\/strong>, bo obiekt klasy pochodnej nie zachowuje si\u0119 jak jego klasa bazowa.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nclass PrefabElement {\n    protected String name;\n\n    public PrefabElement(String name) {\n        this.name = name;\n    }\n\n    public void transport() {\n        System.out.println(&quot;Transporting &quot; + name + &quot; to construction site...&quot;);\n    }\n}\n\n\nclass TemporaryElement extends PrefabElement {\n    public TemporaryElement(String name) {\n        super(name);\n    }\n\n\n    @Override\n    public void transport() {\n        \/\/ Naruszenie LSP \u2014 ta klasa nie powinna by\u0107 transportowana!\n        throw new UnsupportedOperationException(&quot;Temporary elements cannot be transported!&quot;);\n    }\n}\n\n\npublic class Main {\n    public static void transportElement(PrefabElement element) {\n        element.transport();\n    }\n\n\n    public static void main(String&#x5B;] args) {\n        PrefabElement beam = new PrefabElement(&quot;Beam&quot;);\n        TemporaryElement testSample = new TemporaryElement(&quot;Test Sample&quot;);\n\n        transportElement(beam);          \/\/ OK\n        transportElement(testSample);    \/\/ B\u0142\u0105d! Naruszenie LSP\n    }\n}\n<\/pre><\/div>\n\n\n<figure class=\"wp-block-image size-large\"><img data-opt-id=1115314622  data-opt-src=\"https:\/\/mlb55nihrfbl.i.optimole.com\/w:1024\/h:681\/q:mauto\/ig:avif\/https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/wp-content\/uploads\/2025\/10\/trucks-minibuses-located-inside-ferryboat-greece.jpg\"  decoding=\"async\" width=\"1024\" height=\"681\" src=\"data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%201024%20681%22%20width%3D%221024%22%20height%3D%22681%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Crect%20width%3D%221024%22%20height%3D%22681%22%20fill%3D%22transparent%22%2F%3E%3C%2Fsvg%3E\" alt=\"\" class=\"wp-image-258\" old-srcset=\"https:\/\/mlb55nihrfbl.i.optimole.com\/w:1024\/h:681\/q:mauto\/ig:avif\/https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/wp-content\/uploads\/2025\/10\/trucks-minibuses-located-inside-ferryboat-greece-scaled.jpg 1024w, https:\/\/mlb55nihrfbl.i.optimole.com\/w:300\/h:200\/q:mauto\/ig:avif\/https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/wp-content\/uploads\/2025\/10\/trucks-minibuses-located-inside-ferryboat-greece-scaled.jpg 300w, https:\/\/mlb55nihrfbl.i.optimole.com\/w:768\/h:511\/q:mauto\/ig:avif\/https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/wp-content\/uploads\/2025\/10\/trucks-minibuses-located-inside-ferryboat-greece-scaled.jpg 768w, https:\/\/mlb55nihrfbl.i.optimole.com\/w:1536\/h:1022\/q:mauto\/ig:avif\/https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/wp-content\/uploads\/2025\/10\/trucks-minibuses-located-inside-ferryboat-greece-scaled.jpg 1536w, https:\/\/mlb55nihrfbl.i.optimole.com\/w:1622\/h:1080\/q:mauto\/ig:avif\/https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/wp-content\/uploads\/2025\/10\/trucks-minibuses-located-inside-ferryboat-greece-scaled.jpg 2048w\" \/><figcaption class=\"wp-element-caption\">Designed by Freepik<\/figcaption><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p><strong>PO<\/strong><\/p>\n\n\n\n<p style=\"font-size:18px\">Zamiast \u0142ama\u0107 zasad\u0119 LSP, mo\u017cna przebudowa\u0107 hierarchi\u0119 klas tak, by tylko <strong>transportowalne elementy<\/strong> dziedziczy\u0142y po <code>PrefabElement<\/code>, a inne implementowa\u0142y inny interfejs lub klas\u0119 bazow\u0105.<\/p>\n\n\n\n<p>Teraz klasy s\u0105 zaprojektowane zgodnie z zasad\u0105 LSP:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>PrefabElement<\/code> mo\u017cna bezpiecznie przetransportowa\u0107,<\/li>\n\n\n\n<li><code>TemporaryElement<\/code> istnieje niezale\u017cnie i nie psuje zachowania systemu.<\/li>\n<\/ul>\n\n\n\n<p>Nie dochodzi do sytuacji, w kt\u00f3rej klasa pochodna \u0142amie oczekiwania klasy bazowej.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nabstract class Element {\n    protected String name;\n\n    public Element(String name) {\n        this.name = name;\n    }\n\n    public String getName() {\n        return name;\n    }\n}\n\nabstract class TransportableElement extends Element {\n    public TransportableElement(String name) {\n        super(name);\n    }\n\n    public abstract void transport();\n}\n\nclass PrefabElement extends TransportableElement {\n    public PrefabElement(String name) {\n        super(name);\n    }\n\n    @Override\n    public void transport() {\n        System.out.println(&quot;Transporting &quot; + name + &quot; to construction site...&quot;);\n    }\n}\n\nclass TemporaryElement extends Element {\n    public TemporaryElement(String name) {\n        super(name);\n    }\n\n    public void analyze() {\n        System.out.println(&quot;Analyzing &quot; + name + &quot; in laboratory...&quot;);\n    }\n}\n\npublic class Main {\n    public static void transportElement(TransportableElement element) {\n        element.transport();\n    }\n\n    public static void main(String&#x5B;] args) {\n        PrefabElement beam = new PrefabElement(&quot;Beam&quot;);\n        TemporaryElement sample = new TemporaryElement(&quot;Test Sample&quot;);\n\n        transportElement(beam);      \/\/ OK\n        \/\/ transportElement(sample); \/\/ Kompilator nie pozwoli \u2013 i o to chodzi!\n\n        sample.analyze();            \/\/ Dzia\u0142a niezale\u017cnie\n    }\n}\n<\/pre><\/div><\/div>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-columns alignwide is-layout-flex wp-container-core-columns-is-layout-d2da2050 wp-block-columns-is-layout-flex\" style=\"margin-bottom:0\">\n<div class=\"wp-block-column has-text-color has-background has-link-color wp-elements-2829207358e174eeb0154d27d8bfd66a is-layout-flow wp-block-column-is-layout-flow\" style=\"color:#000000;background-color:#ffe97d;padding-top:2em;padding-right:2em;padding-bottom:2em;padding-left:2em\">\n<p class=\"has-normal-font-size\" style=\"line-height:1.5\"><strong>Kiedy zasada jest wa\u017cna?<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-text-color has-css-opacity has-background is-style-wide\" style=\"background-color:#000000;color:#000000\"\/>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Gdy budujesz hierarchi\u0119 klas w systemie (np. r\u00f3\u017cne typy prefabrykat\u00f3w),<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Gdy stosujesz polimorfizm i chcesz mie\u0107 pewno\u015b\u0107, \u017ce zamiana obiekt\u00f3w nie zmieni zachowania programu.<\/li>\n<\/ul>\n<\/div>\n\n\n\n<div class=\"wp-block-column has-text-color has-background has-link-color wp-elements-a050fda24002dada58b17dfcca445fe3 is-layout-flow wp-block-column-is-layout-flow\" style=\"color:#000000;background-color:#d1d1e1;padding-top:2em;padding-right:2em;padding-bottom:2em;padding-left:2em\">\n<p class=\"has-normal-font-size\" style=\"line-height:1.5\"><strong>Na co zwraca\u0107 uwag\u0119:<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity is-style-wide\"\/>\n\n\n\n<ul class=\"wp-block-list has-normal-font-size\">\n<li>Nie ka\u017cda relacja mi\u0119dzy klasami powinna by\u0107 dziedziczeniem,<\/li>\n\n\n\n<li>Klasy pochodne nie powinny ogranicza\u0107 zachowania klas bazowych,<\/li>\n\n\n\n<li>Je\u015bli dana klasa nie mo\u017ce spe\u0142nia\u0107 wszystkich wymaga\u0144 bazowej \u2013 to znak, \u017ce potrzebna jest inna hierarchia.<\/li>\n<\/ul>\n<\/div>\n\n\n\n<div class=\"wp-block-column has-text-color has-background has-link-color wp-elements-c4e725d658ca9a4d1cd62e301e11ba9a is-layout-flow wp-block-column-is-layout-flow\" style=\"color:#000000;background-color:#c0ebf1;padding-top:2em;padding-right:2em;padding-bottom:2em;padding-left:2em\">\n<p class=\"has-normal-font-size\"><strong>Trudno\u015bci:<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-css-opacity is-style-wide\"\/>\n\n\n\n<ul class=\"wp-block-list has-normal-font-size\">\n<li>Pocz\u0105tkuj\u0105cy cz\u0119sto nadu\u017cywaj\u0105 dziedziczenia zamiast kompozycji,<\/li>\n\n\n\n<li>LSP wymaga my\u015blenia o tym, <em>jak obiekty b\u0119d\u0105 u\u017cywane w kontek\u015bcie<\/em>, a nie tylko jak s\u0105 zbudowane.<\/li>\n<\/ul>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Przyk\u0142ady przed i po zastosowaniu zasady PRZED Poni\u017cszy przyk\u0142ad \u0142amie zasad\u0119 Liskov, bo klasa TemporaryElement zmienia zachowanie metody transport, w spos\u00f3b sprzeczny z klas\u0105 bazow\u0105. Kod oczekuje, \u017ce ka\u017cda instancja PrefabElement ma metod\u0119 transport, kt\u00f3ra dzia\u0142a poprawnie.Jednak TemporaryElement zmienia jej zachowanie \u2014 powoduje wyj\u0105tek.To \u0142amie zasad\u0119 podstawienia Liskov, bo obiekt klasy pochodnej nie zachowuje si\u0119 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":256,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[],"class_list":["post-255","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-solid"],"_links":{"self":[{"href":"https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/index.php?rest_route=\/wp\/v2\/posts\/255","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=255"}],"version-history":[{"count":4,"href":"https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/index.php?rest_route=\/wp\/v2\/posts\/255\/revisions"}],"predecessor-version":[{"id":295,"href":"https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/index.php?rest_route=\/wp\/v2\/posts\/255\/revisions\/295"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/index.php?rest_route=\/wp\/v2\/media\/256"}],"wp:attachment":[{"href":"https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=255"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=255"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ewelina-beben.profesjonalnyprogramista.pl\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=255"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}