<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ oop - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ oop - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 26 Jul 2026 14:13:14 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/oop/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ What is Polymorphism in Python? Explained with an Example ]]>
                </title>
                <description>
                    <![CDATA[ Polymorphism is an object-oriented programming (OOP) principle that helps you write high quality, flexible, maintainable, reusable, testable, and readable software. If you plan to work with object-oriented software, it is crucial to understand polymo... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-polymorphism-in-python-example/</link>
                <guid isPermaLink="false">67a4d16ab891dd1403996d28</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Object Oriented Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ oop ]]>
                    </category>
                
                    <category>
                        <![CDATA[ design patterns ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Danny ]]>
                </dc:creator>
                <pubDate>Thu, 06 Feb 2025 15:12:42 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1738335631634/ef8f79a0-73df-430c-b955-a5325ca22f04.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Polymorphism is an object-oriented programming (OOP) principle that helps you write high quality, flexible, maintainable, reusable, testable, and readable software. If you plan to work with object-oriented software, it is crucial to understand polymorphism.</p>
<h2 id="heading-what-is-polymorphism">What is Polymorphism?</h2>
<p>The word <em>polymorphism</em> is derived from Greek, and means "having multiple forms":</p>
<ul>
<li><p>Poly = many</p>
</li>
<li><p>Morph = forms</p>
</li>
</ul>
<p><strong>In programming, polymorphism is the ability of an object to take many forms</strong>.</p>
<p>The key advantage of polymorphism is that it allows us to write more <strong>generic</strong> and <strong>reusable</strong> code. Instead of writing separate logic for different classes, we define common behaviours in a parent class and let child classes override them as needed. This eliminates the need for excessive <code>if-else</code> checks, making the code more maintainable and extensible.</p>
<p>MVC frameworks like <a target="_blank" href="http://djangoproject.com/">Django</a> use polymorphism to make code more flexible. For example, Django supports different databases like SQLite, MySQL, and PostgreSQL. Normally, each database requires different code to interact with it, but Django provides a single database API that works with all of them. This means you can write the same code for database operations, no matter which database you use. So, if you start a project with SQLite and later switch to PostgreSQL, you won’t need to rewrite much of your code, thanks to polymorphism.</p>
<p>In this article, to make things easy to understand, I’ll show you a bad code example with no polymorphism. We’ll discuss the issues that this bad code causes, and then solve the issues by refactoring the code to use polymorphism.</p>
<p>(Btw, if you learn better by video, checkout my <a target="_blank" href="https://youtu.be/zuPg8_qsL7A">Polymorphism in Python</a> YouTube video.)</p>
<h2 id="heading-first-an-example-with-no-polymorphism">First, an example with no polymorphism:</h2>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Car</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, brand, model, year, number_of_doors</span>):</span>
        self.brand = brand
        self.model = model
        self.year = year
        self.number_of_doors = number_of_doors

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">start</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">"Car is starting."</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">stop</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">"Car is stopping."</span>)
</code></pre>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Motorcycle</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, brand, model, year</span>):</span>
        self.brand = brand
        self.model = model
        self.year = year

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">start_bike</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">"Motorcycle is starting."</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">stop_bike</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">"Motorcycle is stopping."</span>)
</code></pre>
<p>Let’s say that we want to create a list of vehicles, then loop through it and perform an inspection on each vehicle:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Create list of vehicles to inspect</span>
vehicles = [
    Car(<span class="hljs-string">"Ford"</span>, <span class="hljs-string">"Focus"</span>, <span class="hljs-number">2008</span>, <span class="hljs-number">5</span>),
    Motorcycle(<span class="hljs-string">"Honda"</span>, <span class="hljs-string">"Scoopy"</span>, <span class="hljs-number">2018</span>),
]

<span class="hljs-comment"># Loop through list of vehicles and inspect them</span>
<span class="hljs-keyword">for</span> vehicle <span class="hljs-keyword">in</span> vehicles:
    <span class="hljs-keyword">if</span> isinstance(vehicle, Car):
        print(<span class="hljs-string">f"Inspecting <span class="hljs-subst">{vehicle.brand}</span> <span class="hljs-subst">{vehicle.model}</span> (<span class="hljs-subst">{type(vehicle).__name__}</span>)"</span>)
        vehicle.start()
        vehicle.stop()
    <span class="hljs-keyword">elif</span> isinstance(vehicle, Motorcycle):
        print(<span class="hljs-string">f"Inspecting <span class="hljs-subst">{vehicle.brand}</span> <span class="hljs-subst">{vehicle.model}</span> (<span class="hljs-subst">{type(vehicle).__name__}</span>)"</span>)
        vehicle.start_bike()
        vehicle.stop_bike()
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">raise</span> Exception(<span class="hljs-string">"Object is not a valid vehicle"</span>)
</code></pre>
<p>Notice the ugly code inside the <code>for</code> loop! Because <code>vehicles</code> is a list of any type of object, we have to figure out what type of object we are dealing with inside each loop before we can access any information on the object.</p>
<p>This code will continue to get uglier as we add more vehicle types. For example, if we <em>extended</em> our codebase to include a new <code>Plane</code> class, then we’d need to <em>modify</em> (and potentially break) existing code – we’d have to add another conditional check in the <code>for</code> loop for planes.</p>
<h3 id="heading-introducing-polymorphism"><strong>Introducing: Polymorphism…</strong></h3>
<p>Cars and motorcycles are both vehicles. They both share some common properties and methods. So, let’s create a parent class that contains these shared properties and methods:</p>
<p>Parent class (or "superclass"):</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Vehicle</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, brand, model, year</span>):</span>
        self.brand = brand
        self.model = model
        self.year = year

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">start</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">"Vehicle is starting."</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">stop</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">"Vehicle is stopping."</span>)
</code></pre>
<p><code>Car</code> and <code>Motorcycle</code> can now <em>inherit</em> from <code>Vehicle</code>. Let’s create the child classes (or "subclasses") of the <code>Vehicle</code> superclass:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Car</span>(<span class="hljs-params">Vehicle</span>):</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, brand, model, year, number_of_doors</span>):</span>
        super().__init__(brand, model, year)
        self.number_of_doors = number_of_doors

    <span class="hljs-comment"># Below, we "override" the start and stop methods, inherited from Vehicle, to provide car-specific behaviour</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">start</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">"Car is starting."</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">stop</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">"Car is stopping."</span>)
</code></pre>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Motorcycle</span>(<span class="hljs-params">Vehicle</span>):</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, brand, model, year</span>):</span>
        super().__init__(brand, model, year)

    <span class="hljs-comment"># Below, we "override" the start and stop methods, inherited from Vehicle, to provide bike-specific behaviour</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">start</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">"Motorcycle is starting."</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">stop</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">"Motorcycle is stopping."</span>)
</code></pre>
<p><code>Car</code> and <code>Motorcycle</code> both extend <code>Vehicle</code>, as they are vehicles. But what’s the point in <code>Car</code> and <code>Motorcycle</code> both extending <code>Vehicle</code> if they are going to implement their own versions of the <code>start()</code> and <code>stop()</code> methods? Look at the code below:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Create list of vehicles to inspect</span>
vehicles = [Car(<span class="hljs-string">"Ford"</span>, <span class="hljs-string">"Focus"</span>, <span class="hljs-number">2008</span>, <span class="hljs-number">5</span>), Motorcycle(<span class="hljs-string">"Honda"</span>, <span class="hljs-string">"Scoopy"</span>, <span class="hljs-number">2018</span>)]

<span class="hljs-comment"># Loop through list of vehicles and inspect them</span>
<span class="hljs-keyword">for</span> vehicle <span class="hljs-keyword">in</span> vehicles:
    <span class="hljs-keyword">if</span> isinstance(vehicle, Vehicle):
        print(<span class="hljs-string">f"Inspecting <span class="hljs-subst">{vehicle.brand}</span> <span class="hljs-subst">{vehicle.model}</span> (<span class="hljs-subst">{type(vehicle).__name__}</span>)"</span>)
        vehicle.start()
        vehicle.stop()
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">raise</span> Exception(<span class="hljs-string">"Object is not a valid vehicle"</span>)
</code></pre>
<p><strong>In this example</strong>:</p>
<ul>
<li><p>We have a list, <code>vehicles</code>, containing instances of both <code>Car</code> and <code>Motorcycle</code>.</p>
</li>
<li><p>We iterate through each vehicle in the list and perform a general inspection on each one.</p>
</li>
<li><p>The inspection process involves starting the vehicle, checking its brand and model, and stopping it afterwards.</p>
</li>
<li><p>Despite the vehicles being of different types, polymorphism allows us to treat them all as instances of the base <code>Vehicle</code> class. The specific implementations of the <code>start()</code> and <code>stop()</code> methods for each vehicle type are invoked dynamically at runtime, based on the actual type of each vehicle.</p>
</li>
</ul>
<p>Because the list can <em>only</em> contain objects that extend the <code>Vehicle</code> class, we know that every object will share some common fields and methods. This means that we can safely call them, without having to worry about whether each specific vehicle has these fields or methods.</p>
<p>This demonstrates how polymorphism enables code to be written in a more generic and flexible manner, allowing for easy extension and maintenance as new types of vehicles are added to the system.</p>
<p>For example, if we wanted to add another vehicle to the list, we don’t have to modify the code used to inspect vehicles (“the client code”). Instead, we can just <em>extend</em> our code base (that is, create a new class), without <em>modifying</em> existing code:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Plane</span>(<span class="hljs-params">Vehicle</span>):</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, brand, model, year, number_of_doors</span>):</span>
        super().__init__(brand, model, year)
        self.number_of_doors = number_of_doors

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">start</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">"Plane is starting."</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">stop</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">"Plane is stopping."</span>)
</code></pre>
<pre><code class="lang-python"><span class="hljs-comment"># Create list of vehicles to inspect</span>
vehicles = [
    Car(<span class="hljs-string">"Ford"</span>, <span class="hljs-string">"Focus"</span>, <span class="hljs-number">2008</span>, <span class="hljs-number">5</span>),
    Motorcycle(<span class="hljs-string">"Honda"</span>, <span class="hljs-string">"Scoopy"</span>, <span class="hljs-number">2018</span>),

    <span class="hljs-comment">########## ADD A PLANE TO THE LIST: #########</span>

    Plane(<span class="hljs-string">"Boeing"</span>, <span class="hljs-string">"747"</span>, <span class="hljs-number">2015</span>, <span class="hljs-number">16</span>),

    <span class="hljs-comment">############################################</span>
]
</code></pre>
<p>The code to perform the vehicle inspections doesn’t have to change to account for a plane. Everything still works, without having to modify our inspection logic.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Polymorphism allows clients to treat different types of objects in the same way. This greatly improves the flexibility of software and maintainability of software, as new classes can be created without you having to modify (often by adding extra <code>if</code>/<code>else if</code> blocks) existing working and tested code.</p>
<h2 id="heading-further-learning">Further Learning</h2>
<p>Polymorphism is related to many other object-oriented programming principles, such as <em>dependency injection</em> and the <em>open-closed</em> SOLID principle. If you’d like to master OOP, then check out my Udemy course:</p>
<ul>
<li><a target="_blank" href="https://www.udemy.com/course/python-oop-object-oriented-programming-from-beginner-to-pro">Python OOP: Object Oriented Programming From Beginner to Pro 🎥</a></li>
</ul>
<p>If you prefer book to video, check out my books:</p>
<ul>
<li><p><a target="_blank" href="https://www.amazon.com/dp/B0DR6ZPZQ8">Amazon Kindle and paperback 📖</a></p>
</li>
<li><p><a target="_blank" href="https://doabledanny.gumroad.com/l/python-oop-beginner-to-pro">Gumroad PDF 📖</a></p>
</li>
</ul>
<p>Thanks for reading :)</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
