{"id":235,"date":"2026-01-02T05:13:50","date_gmt":"2026-01-02T05:13:50","guid":{"rendered":"http:\/\/leif.sahyun.net\/main\/?p=235"},"modified":"2026-01-03T22:09:45","modified_gmt":"2026-01-03T22:09:45","slug":"why-object-oriented-inheritance-is-bad-and-how-to-fix-it","status":"publish","type":"post","link":"http:\/\/leif.sahyun.net\/main\/?p=235","title":{"rendered":"Why Object Oriented Inheritance Is Bad and How to Fix It"},"content":{"rendered":"\n<p>Inheritance in object-oriented design can be a useful concept for organizing code and reusing functionality. At its core, inheritance allows a new class to derive properties and behaviors from an existing class which allows reusing functionality without duplicating it. By inheriting from a base class, the subclass automatically gains access to all the parent&#8217;s public and protected methods and fields. For instance, a Chicken class could inherit from a Bird class that defines methods for flying and laying eggs that are common to all birds.<\/p>\n\n\n\n<p>Standard inheritance like this can lead to categorization dilemmas also seen in taxonomic classification structures in other fields, when you need to model something like a platypus that uses properties and behaviors from more than one parent class. In this case you would need to select one class to be the parent and reimplement behaviors needed from the other possible parent class, leading to code duplication &#8211; ugh!<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"343\" height=\"231\" src=\"http:\/\/leif.sahyun.net\/main\/wp-content\/uploads\/2026\/01\/PlatypusTaxonomy.drawio.png\" alt=\"\" class=\"wp-image-239\" style=\"aspect-ratio:1.4849187935034802;object-fit:cover;width:400px\" srcset=\"http:\/\/leif.sahyun.net\/main\/wp-content\/uploads\/2026\/01\/PlatypusTaxonomy.drawio.png 343w, http:\/\/leif.sahyun.net\/main\/wp-content\/uploads\/2026\/01\/PlatypusTaxonomy.drawio-300x202.png 300w\" sizes=\"auto, (max-width: 343px) 100vw, 343px\" \/><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>### Implementation with standard inheritance\nclass Bird:\n&nbsp;&nbsp;&nbsp;&nbsp;def lay(self):\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(\"laid egg\")\n\nclass Mammal:\n&nbsp;&nbsp;&nbsp;&nbsp;def pet(self):\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(\"petting fuzzy animal, aw...\")\n\nclass Platypus(Mammal):\n&nbsp;&nbsp;&nbsp;&nbsp;# CODE DUPLICATION!!! &gt;:(\n&nbsp;&nbsp;&nbsp;&nbsp;def lay(self):\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(\"laid egg\")\n\nplaty = Platypus()\nplaty.pet() #petting fuzzy animal\nplaty.lay() #laid egg\nprint(f\"Platypus is a Mammal: {isinstance(platy, Mammal)}\") #true\nprint(f\"Platypus is a Bird: {isinstance(platy, Bird)}\") #false<\/code><\/pre>\n\n\n\n<p>This occurs frequently in industry when features are added to one class hierarchy and then need to be added to another later. Therefore, some standard approaches have been developed to handle sharing functionality outside of strict class hierarchies. Composition with dependency injection is the most popular approach and it is good practice to build features with composition instead of inheritance when possible. Several languages, including Python, also support multiple inheritance, where a class can inherit from multiple parents, adopting some properties of each.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Multiple Inheritance<\/h2>\n\n\n\n<p>In languages that support multiple inheritance, there is a direct way to model a class that needs functionality from two unrelated parents: just inherit both of them. Declaring a class Platypus(Mammal, Bird) provides all the functionality needed, but can produce ambiguity between properties of the class with the same name between the two parents. Additionally, when properties for an object are initialized, there will be only one initializer defined for the child class, which will need to have knowledge of the initializer definitions for each of its parents. Still, with a defined order for method resolution and proper initialization, this can work without code duplication or a great deal of framework code.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"261\" height=\"221\" src=\"http:\/\/leif.sahyun.net\/main\/wp-content\/uploads\/2026\/01\/MultipleInheritance.drawio.png\" alt=\"\" class=\"wp-image-240\" style=\"width:400px\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Dependency Injection<\/h2>\n\n\n\n<p>With a dependency injection approach, rather than inheriting behavior from a parent class, objects have a collection of components that they can refer to methods or properties of as needed in order to implement their behavior. This adds flexibility by allowing you to pass a full initialized object as a dependency for a new object, and allows you to implement multiple components matching the same interface for a dependency with different implementations to customize behavior. However, this approach doesn\u2019t produce the same outcomes as inheritance as the methods of the components are not available on the composed object unless you define pass-through methods to call the appropriate component. It also breaks is-a relationships for type checks if those are needed in your application.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"261\" height=\"141\" src=\"http:\/\/leif.sahyun.net\/main\/wp-content\/uploads\/2026\/01\/PlatypusComposition.drawio.png\" alt=\"\" class=\"wp-image-241\" style=\"width:400px\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Compositional Inheritance<\/h2>\n\n\n\n<p>What if we combine the multiple inheritance and dependency injection approaches? That way you can have a class adhering to an interface you need (as in the case of inherited methods being available on the object) and provide a default implementation of the interface by an injected component. I have created a basic implementation of Python decorators here: <a href=\"\/main\/compositional_inheritance.py\">compositional_inheritance.py<\/a> that combines these approaches by accepting additional constructor arguments on any decorated class for components matching interfaces while also adding passthrough method definitions for each method available on the components. This way each component retains its own data, can be replaced with alternate components for customization, and exposes the behavior we need on the composed class.<\/p>\n\n\n\n<p>Here is what the platypus example would look like with this approach:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class EggLaying:\n&nbsp;&nbsp;&nbsp;&nbsp;def lay(self):\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(\"laid egg\")\n\nclass Fuzzy:\n&nbsp;&nbsp;&nbsp;&nbsp;def pet(self):\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(\"petting fuzzy animal, aw...\")\n\n@components(EggLaying, Fuzzy)\nclass Platypus:\n&nbsp;&nbsp;&nbsp;&nbsp;pass # No code duplication! :)<\/code><\/pre>\n\n\n\n<p>With the simple example we\u2019ve been working with, this is identical to a multiple inheritance, because the component classes don\u2019t have conflicting properties and we don\u2019t need to switch out any of the components. Here\u2019s a slightly more detailed example with multiple levels of components and swapping components to customize behavior:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Moveable:\n&nbsp;&nbsp;&nbsp;&nbsp;def move(self):\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return \"walks\"\n\nclass Swimming:\n&nbsp;&nbsp;&nbsp;&nbsp;def move(self):\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return \"swims\"\n\nclass Flying:\n&nbsp;&nbsp;&nbsp;&nbsp;def move(self):\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return \"flies\"\n\nclass Feedable:\n&nbsp;&nbsp;&nbsp;&nbsp;def feed(self):\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return \"eats meat\"\n\n@components(Moveable, Feedable)\nclass Animal:\n&nbsp;&nbsp;&nbsp;&nbsp;def __init__(self, name):\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.name = name\n&nbsp;&nbsp;&nbsp;&nbsp;def describe(self):\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print(f\"{self.name} is an animal that {self.move()} and {self.feed()}\")\n\nsomething = Animal(\"default\")\nsomething.describe()\n\n@components((Animal, &#91;\"shark\"], {'_component_Moveable': Swimming()}))\nclass Shark:\n&nbsp;&nbsp;&nbsp;&nbsp;pass\n\nshark = Shark()\nshark.describe()\n\nsharknado = Shark(_component_Animal=Animal(\"sharknado\", _component_Moveable=Flying()))\nsharknado.describe()\n\n# In some cases, you can create objects that would otherwise need a new subclass with just a new component\n\n@components(Feedable)\nclass Laser:\n&nbsp;&nbsp;&nbsp;&nbsp;def feed(self):\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return self._component_Feedable.feed() + \"... *fried*\"\n\nlaser_sharknado = Shark(_component_Animal=Animal(\"laser_sharknado\", _component_Moveable=Flying(), _component_Feedable=Laser()))\nlaser_sharknado.describe()<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Inheritance in object-oriented design can be a useful concept for organizing code and reusing functionality. At its core, inheritance allows a new class to derive properties and behaviors from an existing class which allows reusing functionality without duplicating it. By inheriting from a base class, the subclass automatically gains access to all the parent&#8217;s public [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":239,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"pagelayer_contact_templates":[],"_pagelayer_content":"","footnotes":""},"categories":[1],"tags":[],"class_list":["post-235","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"_links":{"self":[{"href":"http:\/\/leif.sahyun.net\/main\/index.php?rest_route=\/wp\/v2\/posts\/235","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/leif.sahyun.net\/main\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/leif.sahyun.net\/main\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/leif.sahyun.net\/main\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/leif.sahyun.net\/main\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=235"}],"version-history":[{"count":5,"href":"http:\/\/leif.sahyun.net\/main\/index.php?rest_route=\/wp\/v2\/posts\/235\/revisions"}],"predecessor-version":[{"id":266,"href":"http:\/\/leif.sahyun.net\/main\/index.php?rest_route=\/wp\/v2\/posts\/235\/revisions\/266"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/leif.sahyun.net\/main\/index.php?rest_route=\/wp\/v2\/media\/239"}],"wp:attachment":[{"href":"http:\/\/leif.sahyun.net\/main\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=235"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/leif.sahyun.net\/main\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=235"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/leif.sahyun.net\/main\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=235"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}