<?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[ Object Oriented Programming - 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[ Object Oriented Programming - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 17 May 2026 11:35:56 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/object-oriented-programming/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How the Factory and Abstract Factory Design Patterns Work in Flutter ]]>
                </title>
                <description>
                    <![CDATA[ In software development, particularly object-oriented programming and design, object creation is a common task. And how you manage this process can impact your app's flexibility, scalability, and maintainability. Creational design patterns govern how... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-the-factory-and-abstract-factory-design-patterns-work-in-flutter/</link>
                <guid isPermaLink="false">6978f477116625d0304ed264</guid>
                
                    <category>
                        <![CDATA[ design patterns ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Flutter ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Factory Design Pattern ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Mobile Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Mobile apps ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Developer ]]>
                    </category>
                
                    <category>
                        <![CDATA[ OOPS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Object Oriented Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ design principles ]]>
                    </category>
                
                    <category>
                        <![CDATA[ object oriented design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Dart ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Abstract Factory Patterns ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Oluwaseyi Fatunmole ]]>
                </dc:creator>
                <pubDate>Tue, 27 Jan 2026 17:23:03 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1769533734673/8b5ad88a-13d2-4fec-969b-55fd854df5c1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In software development, particularly object-oriented programming and design, object creation is a common task. And how you manage this process can impact your app's flexibility, scalability, and maintainability.</p>
<p>Creational design patterns govern how classes and objects are created in a systematic and scalable way. They provide blueprints for creating objects so you don't repeat code. They also keep your system consistent and makes your app easy to extend.</p>
<p>There are five major Creational Design patterns:</p>
<ol>
<li><p><strong>Singleton:</strong> Ensures a class has only one instance and provides a global point of access to it.</p>
</li>
<li><p><strong>Factory Method</strong>: Provides an interface for creating objects but lets subclasses decide which class to instantiate.</p>
</li>
<li><p><strong>Abstract Factory</strong>: Creates families of related objects without specifying their concrete classes.</p>
</li>
<li><p><strong>Builder</strong>: Allows you to construct complex objects step by step, separating construction from representation.</p>
</li>
<li><p><strong>Prototype</strong>: Creates new objects by cloning existing ones, rather than creating from scratch.</p>
</li>
</ol>
<p>Each of these patterns solves specific problems around object creation, depending on the complexity and scale of your application.</p>
<p>In this tutorial, I'll explain what Creational Design Patterns are and how they work. We'll focus on two primary patterns: the Factory and Abstract Factory patterns.</p>
<p>Many people mix these two up, so here we'll explore:</p>
<ol>
<li><p>How each pattern works</p>
</li>
<li><p>Practical examples in Flutter</p>
</li>
<li><p>Applications, best practices, and usage</p>
</li>
</ol>
<p>By the end, you'll understand when to use Factory, when to switch to Abstract Factory, and how to structure your Flutter apps for scalability and maintainability.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-how-the-factory-pattern-works-in-flutter">How the Factory Pattern Works in Flutter</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-step-1-define-the-product-and-abstract-creator">Step 1: Define the Product and Abstract Creator</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-2-implement-concrete-products">Step 2: Implement Concrete Products</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-3-create-the-factory">Step 3: Create the Factory</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-4-use-the-factory">Step 4: Use the Factory</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-factory-pattern-for-security-checks">Factory Pattern for Security Checks</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-the-abstract-factory-pattern-works-in-flutter">How the Abstract Factory Pattern Works in Flutter</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-step-1-define-abstract-product-interfaces">Step 1: Define Abstract Product Interfaces</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-2-implement-platform-specific-products">Step 2: Implement Platform-Specific Products</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-3-define-the-abstract-factory-interface">Step 3: Define the Abstract Factory Interface</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-4-implement-platform-specific-factories">Step 4: Implement Platform Specific Factories</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-5-client-code-using-abstract-factory">Step 5: Client Code Using Abstract Factory</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before diving into this tutorial, you should have:</p>
<ul>
<li><p>a basic understanding of the Dart programming language</p>
</li>
<li><p>familiarity with Object-Oriented Programming (OOP) concepts (particularly classes, inheritance, and abstract classes)</p>
</li>
<li><p>basic knowledge of Flutter development (helpful but not required)</p>
</li>
<li><p>an understanding of interfaces and polymorphism</p>
</li>
<li><p>and experience creating and instantiating classes in Dart.</p>
</li>
</ul>
<h2 id="heading-how-the-factory-pattern-works-in-flutter">How the Factory Pattern Works in Flutter</h2>
<p>You'll typically use the Factory Pattern when you want to manage data sets that might be related, but only for a single type of object.</p>
<p>Let's say you want to manage themes for Android and iOS. Using the Factory Pattern allows you to encapsulate object creation and keep your app modular. We'll build this step by step so you can see how the pattern works.</p>
<h3 id="heading-step-1-define-the-product-and-abstract-creator">Step 1: Define the Product and Abstract Creator</h3>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AppTheme</span> </span>{
  <span class="hljs-built_in">String?</span> data;
  AppTheme({<span class="hljs-keyword">this</span>.data});
}

<span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ApplicationThemeData</span> </span>{
  Future&lt;AppTheme&gt; getApplicationTheme();
}
</code></pre>
<p>Here, <code>AppTheme</code> is a simple data class that holds theme information. This represents the product our factory will create. <code>ApplicationThemeData</code> serves as an abstract base class. This abstraction is crucial because it defines a contract that all concrete theme implementations must follow.</p>
<p>By requiring a <code>getApplicationTheme()</code> method, we ensure consistency across different platforms.</p>
<h3 id="heading-step-2-implement-concrete-products">Step 2: Implement Concrete Products</h3>
<p>Now we create platform-specific implementations that provide actual theme data.</p>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AndroidAppTheme</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ApplicationThemeData</span> </span>{
  <span class="hljs-meta">@override</span>
  Future&lt;AppTheme&gt; getApplicationTheme() <span class="hljs-keyword">async</span> {
    <span class="hljs-keyword">return</span> AppTheme(data: <span class="hljs-string">"Here is android theme"</span>);
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IOSThemeData</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ApplicationThemeData</span> </span>{
  <span class="hljs-meta">@override</span>
  Future&lt;AppTheme&gt; getApplicationTheme() <span class="hljs-keyword">async</span> {
    <span class="hljs-keyword">return</span> AppTheme(data: <span class="hljs-string">"This is IOS theme data"</span>);
  }
}
</code></pre>
<p>The concrete implementations, <code>AndroidAppTheme</code> and <code>IOSThemeData</code>, extend the abstract class and provide platform-specific theme data. Each returns an <code>AppTheme</code> object with content tailored to its respective platform.</p>
<h3 id="heading-step-3-create-the-factory">Step 3: Create the Factory</h3>
<p>The factory encapsulates the object creation logic, so client code doesn't need to know which specific theme class it's working with.</p>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ThemeFactory</span> </span>{
  ThemeFactory({<span class="hljs-keyword">required</span> <span class="hljs-keyword">this</span>.theme});
  ApplicationThemeData theme;

  loadTheme() <span class="hljs-keyword">async</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> theme.getApplicationTheme();
  }
}
</code></pre>
<p><code>ThemeFactory</code> acts as the factory itself. It accepts any <code>ApplicationThemeData</code> implementation and provides a unified <code>loadTheme()</code> method. This encapsulates the object creation logic cleanly.</p>
<h3 id="heading-step-4-use-the-factory">Step 4: Use the Factory</h3>
<p>Finally, we use the factory in our application code.</p>
<pre><code class="lang-dart">ThemeFactory(
  theme: Platform.isAndroid ? AndroidAppTheme() : IOSThemeData()
).loadTheme();
</code></pre>
<p>Here, you choose a theme (Android or iOS) and get the corresponding <code>AppTheme</code>. This approach is simple and effective when you only care about one functionality, like loading a theme.</p>
<p>The beauty of this pattern is that the client code remains clean and doesn't need to change if you add new platforms later.</p>
<h2 id="heading-factory-pattern-for-security-checks">Factory Pattern for Security Checks</h2>
<p>Another excellent use case for the Factory Pattern is when implementing security checks during your application bootstrap.</p>
<p>For instance, Android and iOS require different logic for internal security. Android might check for developer mode or rooted devices, while iOS checks for jailbroken devices. This scenario is a perfect example of when to apply the Factory Pattern, as it allows you to encapsulate platform-specific security logic cleanly and maintainably. Let's implement this step by step.</p>
<h3 id="heading-step-1-define-security-check-result-and-abstract-checker">Step 1: Define Security Check Result and Abstract Checker</h3>
<p>First, we need a standardized way to communicate security check outcomes and a contract for performing security checks.</p>
<pre><code class="lang-dart"><span class="hljs-comment">// Base security check result class</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SecurityCheckResult</span> </span>{
  <span class="hljs-keyword">final</span> <span class="hljs-built_in">bool</span> isSecure;
  <span class="hljs-keyword">final</span> <span class="hljs-built_in">String</span> message;

  SecurityCheckResult({<span class="hljs-keyword">required</span> <span class="hljs-keyword">this</span>.isSecure, <span class="hljs-keyword">required</span> <span class="hljs-keyword">this</span>.message});
}

<span class="hljs-comment">// Abstract security checker</span>
<span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SecurityChecker</span> </span>{
  Future&lt;SecurityCheckResult&gt; performSecurityCheck();
}
</code></pre>
<p>The <code>SecurityCheckResult</code> class provides a standardized way to communicate security check outcomes across platforms.</p>
<p>It contains a boolean flag indicating security status and a descriptive message for the user. The abstract <code>SecurityChecker</code> class defines the contract that all platform-specific security implementations must follow.</p>
<p>This ensures that, regardless of the platform, we can always call <code>performSecurityCheck()</code> and receive a consistent result type.</p>
<h3 id="heading-step-2-implement-platform-specific-security-checkers">Step 2: Implement Platform-Specific Security Checkers</h3>
<p>Now we create the actual security checking implementations for each platform.</p>
<pre><code class="lang-dart"><span class="hljs-comment">// Android-specific security implementation</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AndroidSecurityChecker</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">SecurityChecker</span> </span>{
  <span class="hljs-meta">@override</span>
  Future&lt;SecurityCheckResult&gt; performSecurityCheck() <span class="hljs-keyword">async</span> {
    <span class="hljs-built_in">bool</span> isRooted = <span class="hljs-keyword">await</span> checkIfDeviceIsRooted();
    <span class="hljs-keyword">if</span> (isRooted) {
      <span class="hljs-keyword">return</span> SecurityCheckResult(
        isSecure: <span class="hljs-keyword">false</span>,
        message: <span class="hljs-string">"Device is rooted. App cannot run on rooted devices."</span>
      );
    }

    <span class="hljs-built_in">bool</span> isDeveloperMode = <span class="hljs-keyword">await</span> checkDeveloperMode();
    <span class="hljs-keyword">if</span> (isDeveloperMode) {
      <span class="hljs-keyword">return</span> SecurityCheckResult(
        isSecure: <span class="hljs-keyword">false</span>,
        message: <span class="hljs-string">"Developer mode is enabled. Please disable it to continue."</span>
      );
    }

    <span class="hljs-keyword">return</span> SecurityCheckResult(
      isSecure: <span class="hljs-keyword">true</span>,
      message: <span class="hljs-string">"Device security check passed."</span>
    );
  }

  Future&lt;<span class="hljs-built_in">bool</span>&gt; checkIfDeviceIsRooted() <span class="hljs-keyword">async</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>; 
  }

  Future&lt;<span class="hljs-built_in">bool</span>&gt; checkDeveloperMode() <span class="hljs-keyword">async</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>; <span class="hljs-comment">// Placeholder</span>
  }
}

<span class="hljs-comment">// iOS-specific security implementation</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IOSSecurityChecker</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">SecurityChecker</span> </span>{
  <span class="hljs-meta">@override</span>
  Future&lt;SecurityCheckResult&gt; performSecurityCheck() <span class="hljs-keyword">async</span> {
    <span class="hljs-built_in">bool</span> isJailbroken = <span class="hljs-keyword">await</span> checkIfDeviceIsJailbroken();

    <span class="hljs-keyword">if</span> (isJailbroken) {
      <span class="hljs-keyword">return</span> SecurityCheckResult(
        isSecure: <span class="hljs-keyword">false</span>,
        message: <span class="hljs-string">"Device is jailbroken. App cannot run on jailbroken devices."</span>
      );
    }

    <span class="hljs-keyword">return</span> SecurityCheckResult(
      isSecure: <span class="hljs-keyword">true</span>,
      message: <span class="hljs-string">"Device security check passed."</span>
    );
  }

  Future&lt;<span class="hljs-built_in">bool</span>&gt; checkIfDeviceIsJailbroken() <span class="hljs-keyword">async</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>; 
  }
}
</code></pre>
<p>The Android implementation focuses on detecting rooted devices and developer mode, which are common security concerns on Android.</p>
<p>A rooted device has elevated permissions that could allow malicious apps to access sensitive data, while developer mode can expose debugging interfaces.</p>
<p>The iOS implementation checks for jailbroken devices, which is the iOS equivalent of rooting. Jailbroken devices bypass Apple's security restrictions and can pose similar security risks.</p>
<h3 id="heading-step-3-create-the-security-factory">Step 3: Create the Security Factory</h3>
<p>The factory wraps the chosen security checker and provides a clean interface for running checks.</p>
<pre><code class="lang-dart"><span class="hljs-comment">// Security Factory</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SecurityCheckFactory</span> </span>{
  SecurityCheckFactory({<span class="hljs-keyword">required</span> <span class="hljs-keyword">this</span>.checker});
  SecurityChecker checker;

  Future&lt;SecurityCheckResult&gt; runSecurityCheck() <span class="hljs-keyword">async</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> checker.performSecurityCheck();
  }
}
</code></pre>
<p>The <code>SecurityCheckFactory</code> provides a simple interface that accepts any <code>SecurityChecker</code> implementation. This means your app initialization code doesn't need to know about platform-specific security details – it just calls <code>runSecurityCheck()</code> and handles the result.</p>
<h3 id="heading-step-4-use-the-security-factory-in-app-bootstrap">Step 4: Use the Security Factory in App Bootstrap</h3>
<p>Finally, we integrate the security factory into our app's initialization process.</p>
<pre><code class="lang-dart"><span class="hljs-comment">// In your app's bootstrap/initialization</span>
Future&lt;<span class="hljs-keyword">void</span>&gt; initializeApp() <span class="hljs-keyword">async</span> {
  <span class="hljs-keyword">final</span> securityFactory = SecurityCheckFactory(
    checker: Platform.isAndroid 
      ? AndroidSecurityChecker() 
      : IOSSecurityChecker()
  );

  <span class="hljs-keyword">final</span> result = <span class="hljs-keyword">await</span> securityFactory.runSecurityCheck();

  <span class="hljs-keyword">if</span> (!result.isSecure) {
    <span class="hljs-comment">// Show error dialog and prevent app from continuing</span>
    showSecurityErrorDialog(result.message);
    <span class="hljs-keyword">return</span>;
  }

  <span class="hljs-comment">// Continue with normal app initialization</span>
  runApp(MyApp());
}
</code></pre>
<p>This usage example demonstrates how the Factory Pattern makes your app initialization code clean and maintainable.</p>
<p>The platform detection happens in one place, the factory handles the creation of the appropriate checker, and your code simply deals with the standardized result.</p>
<p><strong>Key takeaway:</strong> Factory is great when you need one type of object, but you want to abstract away the creation logic.</p>
<h2 id="heading-how-the-abstract-factory-pattern-works-in-flutter">How the Abstract Factory Pattern Works in Flutter</h2>
<p>The Abstract Factory Pattern comes into play when you have more than two data sets for comparison, and each set includes multiple functionalities.</p>
<p>For example, imagine you now want to manage themes, widgets, and architecture for Android, iOS, and Linux. Managing this with just a Factory becomes messy, so Abstract Factory provides a structured way to handle multiple related objects for different platforms.</p>
<p>So let's see how you can handle this using the abstract factory method.</p>
<h3 id="heading-step-1-define-abstract-product-interfaces">Step 1: Define Abstract Product Interfaces</h3>
<p>Before we dive into this implementation, it's important to understand what abstract product interfaces are. An abstract product interface is essentially a contract that defines what methods a product must implement, without specifying how they're implemented.</p>
<p>Think of it as a blueprint that ensures all related products share a common structure. In our case, we're defining three core functionalities that every platform must provide:</p>
<ol>
<li><p>Theme management</p>
</li>
<li><p>Widget handling</p>
</li>
<li><p>Architecture configuration.</p>
</li>
</ol>
<p>By creating these abstract interfaces first, we establish a consistent API that all platform-specific implementations will follow.</p>
<pre><code class="lang-dart"><span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ThemeManager</span> </span>{
  Future&lt;<span class="hljs-built_in">String</span>&gt; getTheme();
}

<span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">WidgetHandler</span> </span>{
  Future&lt;<span class="hljs-built_in">bool</span>&gt; getWidget();
}

<span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ArchitechtureHandler</span> </span>{
  Future&lt;<span class="hljs-built_in">String</span>&gt; getArchitechture();
}
</code></pre>
<p>Here, we’re defining three base functionalities that every platform will implement: theme, widgets, and architecture.</p>
<p>Each interface declares a single method that returns platform-specific information.</p>
<p>The <code>ThemeManager</code> retrieves theme data, <code>WidgetHandler</code> determines widget compatibility, and <code>ArchitechtureHandler</code> provides architecture details.</p>
<h3 id="heading-step-2-implement-platform-specific-products">Step 2: Implement Platform-Specific Products</h3>
<p>Now that we have our abstract interfaces defined, we need to create concrete implementations for each platform. This step is where we provide the actual, platform-specific behavior for each product type. Think of this as filling in the blueprint with real details.</p>
<p>While the abstract interfaces told us what methods we need, these concrete classes tell us how those methods behave on each specific platform. Each platform (Android, iOS, Linux) will have its own unique implementation of themes, widgets, and architecture.</p>
<h4 id="heading-android">Android:</h4>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AndroidThemeManager</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ThemeManager</span> </span>{
  <span class="hljs-meta">@override</span>
  Future&lt;<span class="hljs-built_in">String</span>&gt; getTheme() <span class="hljs-keyword">async</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-string">"Android Theme"</span>;
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AndroidWidgetHandler</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">WidgetHandler</span> </span>{
  <span class="hljs-meta">@override</span>
  Future&lt;<span class="hljs-built_in">bool</span>&gt; getWidget() <span class="hljs-keyword">async</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AndroidArchitechtureHandler</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ArchitechtureHandler</span> </span>{
  <span class="hljs-meta">@override</span>
  Future&lt;<span class="hljs-built_in">String</span>&gt; getArchitechture() <span class="hljs-keyword">async</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-string">"Android Architecture"</span>;
  }
}
</code></pre>
<p>For Android, we're creating three specific product classes. The <code>AndroidThemeManager</code> returns Material Design theme data, the <code>AndroidWidgetHandler</code> returns true to indicate that Android supports home screen widgets, and the <code>AndroidArchitechtureHandler</code> provides information about Android's architecture (which could include details about ARM, x86, or other processor architectures).</p>
<h4 id="heading-ios">iOS:</h4>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IOSThemeManager</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ThemeManager</span> </span>{
  <span class="hljs-meta">@override</span>
  Future&lt;<span class="hljs-built_in">String</span>&gt; getTheme() <span class="hljs-keyword">async</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-string">"IOS Theme"</span>;
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IOSWidgetHandler</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">WidgetHandler</span> </span>{
  <span class="hljs-meta">@override</span>
  Future&lt;<span class="hljs-built_in">bool</span>&gt; getWidget() <span class="hljs-keyword">async</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IOSArchitechtureHandler</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ArchitechtureHandler</span> </span>{
  <span class="hljs-meta">@override</span>
  Future&lt;<span class="hljs-built_in">String</span>&gt; getArchitechture() <span class="hljs-keyword">async</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-string">"iOS Architecture"</span>;
  }
}
</code></pre>
<p>The iOS implementations follow the same structure but provide iOS-specific values. Notice that <code>IOSWidgetHandler</code> returns false, this could represent a scenario where certain widget features aren't available or behave differently on iOS compared to Android.</p>
<h4 id="heading-linux">Linux:</h4>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LinuxThemeManager</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ThemeManager</span> </span>{
  <span class="hljs-meta">@override</span>
  Future&lt;<span class="hljs-built_in">String</span>&gt; getTheme() <span class="hljs-keyword">async</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-string">"Linux Theme"</span>;
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LinuxWidgetHandler</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">WidgetHandler</span> </span>{
  <span class="hljs-meta">@override</span>
  Future&lt;<span class="hljs-built_in">bool</span>&gt; getWidget() <span class="hljs-keyword">async</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LinuxArchitechtureHandler</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ArchitechtureHandler</span> </span>{
  <span class="hljs-meta">@override</span>
  Future&lt;<span class="hljs-built_in">String</span>&gt; getArchitechture() <span class="hljs-keyword">async</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-string">"Linux Architecture"</span>;
  }
}
</code></pre>
<p>Similarly, Linux gets its own set of implementations, providing Linux-specific theme data and architecture information.</p>
<h3 id="heading-step-3-define-the-abstract-factory-interface">Step 3: Define the Abstract Factory Interface</h3>
<p>With our product classes ready, we now need to create the factory that will produce them.</p>
<p>The abstract factory interface is the master blueprint that declares which products our factory must be able to create. This interface doesn't create anything itself, it simply declares that any concrete factory must provide methods to create all three product types (theme, widget, and architecture handlers). This ensures that, regardless of which platform factory we use, we can always access all three functionalities.</p>
<pre><code class="lang-dart"><span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AppFactory</span> </span>{
  ThemeManager themeManager();
  WidgetHandler widgetManager();
  ArchitechtureHandler architechtureHandler();
}
</code></pre>
<p>Here, we define a factory blueprint. Any platform specific factory will have to implement all three functionalities. This guarantees consistency: every platform will have all three capabilities available.</p>
<h3 id="heading-step-4-implement-platform-specific-factories">Step 4: Implement Platform Specific Factories</h3>
<p>This is where everything comes together. We're now creating the actual factories that will produce the platform-specific products we defined earlier. Each factory is responsible for creating all the related products for its platform. The key advantage here is encapsulation: the factory knows how to create all the related objects for a platform, and it ensures they're compatible with each other. For example, <code>AndroidFactory</code> creates Android-specific theme managers, widget handlers, and architecture handlers that all work together seamlessly.</p>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AndroidFactory</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AppFactory</span> </span>{
  <span class="hljs-meta">@override</span>
  ThemeManager themeManager() =&gt; AndroidThemeManager();

  <span class="hljs-meta">@override</span>
  WidgetHandler widgetManager() =&gt; AndroidWidgetHandler();

  <span class="hljs-meta">@override</span>
  ArchitechtureHandler architechtureHandler() =&gt; AndroidArchitechtureHandler();
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">IOSFactory</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AppFactory</span> </span>{
  <span class="hljs-meta">@override</span>
  ThemeManager themeManager() =&gt; IOSThemeManager();

  <span class="hljs-meta">@override</span>
  WidgetHandler widgetManager() =&gt; IOSWidgetHandler();

  <span class="hljs-meta">@override</span>
  ArchitechtureHandler architechtureHandler() =&gt; IOSArchitechtureHandler();
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LinuxFactory</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AppFactory</span> </span>{
  <span class="hljs-meta">@override</span>
  ThemeManager themeManager() =&gt; LinuxThemeManager();

  <span class="hljs-meta">@override</span>
  WidgetHandler widgetManager() =&gt; LinuxWidgetHandler();

  <span class="hljs-meta">@override</span>
  ArchitechtureHandler architechtureHandler() =&gt; LinuxArchitechtureHandler();
}
</code></pre>
<p>Each concrete factory (AndroidFactory, IOSFactory, LinuxFactory) implements all three methods from the <code>AppFactory</code> interface. When you call <code>themeManager()</code> on <code>AndroidFactory</code>, you get an <code>AndroidThemeManager</code>. When you call it on <code>IOSFactory</code>, you get an <code>IOSThemeManager</code>. The same pattern applies to all products.</p>
<h3 id="heading-step-5-client-code-using-abstract-factory">Step 5: Client Code Using Abstract Factory</h3>
<p>Finally, we create the client code that uses our abstract factory. This is the layer that your application will actually interact with. The beauty of this pattern is that the client code doesn't need to know anything about the specific platform implementations, it just works with the abstract factory interface.</p>
<p>The <code>AppBaseFactory</code> class accepts any factory that implements <code>AppFactory</code> and provides a simple method to initialize all platform settings. The <code>CheckDevice</code> class determines which factory to use based on the current platform, completely abstracting this decision away from the rest of your application.</p>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AppBaseFactory</span> </span>{
  AppBaseFactory({<span class="hljs-keyword">required</span> <span class="hljs-keyword">this</span>.<span class="hljs-keyword">factory</span>});
  AppFactory <span class="hljs-keyword">factory</span>;

  getAppSettings() {
    <span class="hljs-keyword">factory</span>
      ..architechtureHandler()
      ..themeManager()
      ..widgetManager();
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CheckDevice</span> </span>{
  <span class="hljs-keyword">static</span> <span class="hljs-keyword">get</span>() {
    <span class="hljs-keyword">if</span> (Platform.isAndroid) <span class="hljs-keyword">return</span> AndroidFactory();
    <span class="hljs-keyword">if</span> (Platform.isIOS) <span class="hljs-keyword">return</span> IOSFactory();
    <span class="hljs-keyword">if</span> (Platform.isLinux) <span class="hljs-keyword">return</span> LinuxFactory();
    <span class="hljs-keyword">throw</span> UnsupportedError(<span class="hljs-string">"Platform not supported"</span>);
  }
}

<span class="hljs-comment">// Usage</span>
AppBaseFactory(<span class="hljs-keyword">factory</span>: CheckDevice.<span class="hljs-keyword">get</span>()).getAppSettings();
</code></pre>
<p>Here's what's happening in this code:</p>
<p>The <code>AppBaseFactory</code> class acts as a wrapper around any <code>AppFactory</code> implementation. It provides a convenient <code>getAppSettings()</code> method that initializes all three components (architecture handler, theme manager, and widget manager) using Dart's cascade notation.</p>
<p>The <code>CheckDevice</code> class contains the platform detection logic. Its static <code>get()</code> method checks the current platform and returns the appropriate factory. This centralizes all platform detection in one place. When you call <code>AppBaseFactory(factory: CheckDevice.get()).getAppSettings()</code>, the code automatically detects your platform, creates the right factory, and initializes all platform-specific components, all without the calling code needing to know any platform-specific details.</p>
<p>Each platform factory produces all related products. The client only interacts with <code>AppBaseFactory</code>, remaining unaware of the internal implementation. This ensures your code is scalable, maintainable, and consistent.</p>
<h2 id="heading-real-world-application-payment-provider-management">Real-World Application: Payment Provider Management</h2>
<p>Another good use case for abstract factory is when you need to switch between multiple payment providers in your application and you only want to expose the necessary functionality to the client (presentation layer).</p>
<p>The abstract factory design pattern properly helps you manage this scenario in terms of concrete implementation, encapsulation, clean code, separation of concerns, and proper code structure and management. For example, you might support Stripe, PayPal, and Flutterwave in your application.</p>
<p>Each provider requires different initialization, transaction processing, and webhook handling. By using the Abstract Factory pattern, you can create a consistent interface for all payment operations while keeping provider-specific details encapsulated within their respective factory implementations.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>You should now feel more comfortable deciding when to use the Factory design pattern vs the Abstract Factory design pattern.</p>
<p>Understanding the factory and abstract factory patterns and their usages properly will help with object creation based on the particular use case you are trying to implement.</p>
<p>The Factory Pattern is ideal when you need one product and want to encapsulate creation logic while the Abstract Factory Pattern works well when you have multiple related products across platforms, need consistency, and want scalability. Using these patterns will help you write clean, maintainable, and scalable Flutter apps.</p>
<p>They give you a systematic approach to object creation and prevent messy, hard-to-maintain code as your app grows.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use the Singleton Design Pattern in Flutter: Lazy, Eager, and Factory Variations ]]>
                </title>
                <description>
                    <![CDATA[ In software engineering, sometimes you need only one instance of a class across your entire application. Creating multiple instances in such cases can lead to inconsistent behavior, wasted memory, or resource conflicts. The Singleton Design Pattern i... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-the-singleton-design-pattern-in-flutter-lazy-eager-and-factory-variations/</link>
                <guid isPermaLink="false">69740b7bc3e68b8de44a179f</guid>
                
                    <category>
                        <![CDATA[ Singleton Design Pattern ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Object Oriented Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ design patterns ]]>
                    </category>
                
                    <category>
                        <![CDATA[ ood ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Flutter ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Dart ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software architecture ]]>
                    </category>
                
                    <category>
                        <![CDATA[ flutter development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Factory Design Pattern ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Mobile Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ mobile app development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Oluwaseyi Fatunmole ]]>
                </dc:creator>
                <pubDate>Fri, 23 Jan 2026 23:59:55 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1769212761076/11d41d2a-8efa-4ddb-9ee2-218f5be00d9f.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In software engineering, sometimes you need only one instance of a class across your entire application. Creating multiple instances in such cases can lead to inconsistent behavior, wasted memory, or resource conflicts.</p>
<p>The Singleton Design Pattern is a creational design pattern that solves this problem by ensuring that a class has exactly one instance and provides a global point of access to it.</p>
<p>This pattern is widely used in mobile apps, backend systems, and Flutter applications for managing shared resources such as:</p>
<ul>
<li><p>Database connections</p>
</li>
<li><p>API clients</p>
</li>
<li><p>Logging services</p>
</li>
<li><p>Application configuration</p>
</li>
<li><p>Security checks during app bootstrap</p>
</li>
</ul>
<p>In this article, we'll explore what the Singleton pattern is, how to implement it in Flutter/Dart, its variations (eager, lazy, and factory), and physical examples. By the end, you'll understand the proper way to use this pattern effectively and avoid common pitfalls.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-the-singleton-pattern">What is the Singleton Pattern?</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-when-to-use-the-singleton-pattern">When to Use the Singleton Pattern</a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-a-singleton-class">How to Create a Singleton Class</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-eager-singleton">Eager Singleton</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-lazy-singleton">Lazy Singleton</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-choosing-between-eager-and-lazy">Choosing Between Eager and Lazy</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-factory-constructors-in-the-singleton-pattern">Factory Constructors in the Singleton Pattern</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-are-factory-constructors">What Are Factory Constructors?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-implementing-singleton-with-factory-constructor">Implementing Singleton with Factory Constructor</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-when-not-to-use-a-singleton">When Not to Use a Singleton</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-why-singletons-can-be-problematic">Why Singletons Can Be Problematic</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-scenarios-where-you-should-avoid-singletons">Scenarios Where You Should Avoid Singletons</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-general-guidelines">General Guidelines</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before diving into this tutorial, you should have:</p>
<ol>
<li><p>Basic understanding of the Dart programming language</p>
</li>
<li><p>Familiarity with Object-Oriented Programming (OOP) concepts, particularly classes and constructors</p>
</li>
<li><p>Basic knowledge of Flutter development (helpful but not required)</p>
</li>
<li><p>Understanding of static variables and methods in Dart</p>
</li>
<li><p>Familiarity with the concept of class instantiation</p>
</li>
</ol>
<h2 id="heading-what-is-the-singleton-pattern">What is the Singleton Pattern?</h2>
<p>The Singleton pattern is a creational design pattern that ensures a class has only one instance and that there is a global point of access to the instance.</p>
<p>Again, this is especially powerful when managing shared resources across an application.</p>
<h3 id="heading-when-to-use-the-singleton-pattern">When to Use the Singleton Pattern</h3>
<p>You should use a Singleton when you are designing parts of your system that must exist once, such as:</p>
<ol>
<li><p>Global app state (user session, auth token, app config)</p>
</li>
<li><p>Shared services (logger, API client, database connection)</p>
</li>
<li><p>Resource heavy logic (encryption handlers, ML models, cache manager)</p>
</li>
<li><p>Application boot security (run platform-specific root/jailbreak checks)</p>
</li>
</ol>
<p>For example, in a Flutter app, Android may check developer mode or root status, while iOS checks jailbroken device state. A Singleton security class is a perfect way to enforce that these checks run once globally during app startup.</p>
<h2 id="heading-how-to-create-a-singleton-class">How to Create a Singleton Class</h2>
<p>We have two major ways of creating a singleton class:</p>
<ol>
<li><p>Eager Instantiation</p>
</li>
<li><p>Lazy Instantiation</p>
</li>
</ol>
<h3 id="heading-eager-singleton">Eager Singleton</h3>
<p>This is where the Singleton is created at load time, whether it's used or not.</p>
<p>In this case, the instance of the singleton class as well as any initialization logic runs at load time, regardless of when this class is actually needed or used. Here's how it works:</p>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">EagerSingleton</span> </span>{
  EagerSingleton._internal();
  <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> EagerSingleton _instance = EagerSingleton._internal();

  <span class="hljs-keyword">static</span> EagerSingleton <span class="hljs-keyword">get</span> instance =&gt; _instance;

  <span class="hljs-keyword">void</span> sayHello() =&gt; <span class="hljs-built_in">print</span>(<span class="hljs-string">"Hello from Eager Singleton"</span>);
}

<span class="hljs-comment">//usage</span>
<span class="hljs-keyword">void</span> main() {
  <span class="hljs-comment">// Accessing the singleton globally</span>
  EagerSingleton.instance.sayHello();
}
</code></pre>
<h4 id="heading-how-the-eager-singleton-works">How the Eager Singleton Works</h4>
<p>Let's break down what's happening in this implementation:</p>
<p>First, <code>EagerSingleton._internal()</code> is a private named constructor (notice the underscore prefix). This prevents external code from creating new instances using <code>EagerSingleton()</code>. The only way to get an instance is through the controlled mechanism we're about to define.</p>
<p>Next, <code>static final EagerSingleton _instance = EagerSingleton._internal();</code> is the key line. This creates the single instance immediately when the class is first loaded into memory. Because it's <code>static final</code>, it belongs to the class itself (not any particular instance) and can only be assigned once. The instance is created right here, at declaration time.</p>
<p>The <code>static EagerSingleton get instance =&gt; _instance;</code> getter provides global access to that single instance. Whenever you call <code>EagerSingleton.instance</code> anywhere in your code, you're getting the exact same object that was created when the class loaded.</p>
<p>Finally, <code>sayHello()</code> is just a regular method to demonstrate that the singleton works. You could replace this with any business logic your singleton needs to perform.</p>
<p>When you run the code in <code>main()</code>, the class loads, the instance is created immediately, and <code>EagerSingleton.instance.sayHello()</code> accesses that pre-created instance to call the method.</p>
<h4 id="heading-pros">Pros:</h4>
<ol>
<li><p>This is simple and thread safe, meaning it's not affected by concurrency, especially when your app runs on multithreads.</p>
</li>
<li><p>It's ideal if the instance is lightweight and may be accessed frequently.</p>
</li>
</ol>
<h4 id="heading-cons">Cons:</h4>
<ol>
<li>If this instance is never used through the runtime, it results in wasted memory and could impact application performance.</li>
</ol>
<h3 id="heading-lazy-singleton">Lazy Singleton</h3>
<p>In this case, the singleton instance is only created when the class is called or needed in runtime. Here, a trigger needs to happen before the instance is created. Let's see an example:</p>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LazySingleton</span> </span>{
  LazySingleton._internal(); 
  <span class="hljs-keyword">static</span> LazySingleton? _instance;

  <span class="hljs-keyword">static</span> LazySingleton <span class="hljs-keyword">get</span> instance {
    _instance ??= LazySingleton._internal();
    <span class="hljs-keyword">return</span> _instance!;
  }

  <span class="hljs-keyword">void</span> sayHello() =&gt; <span class="hljs-built_in">print</span>(<span class="hljs-string">"Hello from LazySingleton"</span>);
}

<span class="hljs-comment">//usage </span>
<span class="hljs-keyword">void</span> main() {
  <span class="hljs-comment">// Accessing the singleton globally</span>
  LazySingleton.instance.sayHello();
}
</code></pre>
<h4 id="heading-how-the-lazy-singleton-works">How the Lazy Singleton Works</h4>
<p>The lazy implementation differs from eager in one crucial way: timing.</p>
<p>Again, <code>LazySingleton._internal()</code> is a private constructor that prevents external instantiation.</p>
<p>But notice that <code>static LazySingleton? _instance;</code> is declared as nullable and not initialized. Unlike the eager version, no instance is created at load time. The variable simply exists as <code>null</code> until it's needed.</p>
<p>The magic happens in the getter: <code>_instance ??= LazySingleton._internal();</code> uses Dart's null-aware assignment operator. This line says "if <code>_instance</code> is null, create a new instance and assign it. Otherwise, keep the existing one." This is the lazy initialization: the instance is only created the first time someone accesses it.</p>
<p>The first time you call <code>LazySingleton.instance</code>, <code>_instance</code> is null, so a new instance is created. Every subsequent call finds that <code>_instance</code> already exists, so it just returns that same instance.</p>
<p>The <code>return _instance!;</code> uses the null assertion operator because we know <code>_instance</code> will never be null at this point (we just ensured it's not null in the previous line).</p>
<p>This approach saves memory because if you never call <code>LazySingleton.instance</code> in your app, the instance never gets created.</p>
<h4 id="heading-pros-1">Pros:</h4>
<ol>
<li><p>Saves application memory, as it only creates what is needed in runtime.</p>
</li>
<li><p>Avoids memory leaks.</p>
</li>
<li><p>Is ideal for resource heavy objects while considering application performance.</p>
</li>
</ol>
<h4 id="heading-cons-1">Cons:</h4>
<ol>
<li>Could be difficult to manage in multithreaded environments, as you have to ensure thread safety while following this pattern.</li>
</ol>
<h3 id="heading-choosing-between-eager-and-lazy">Choosing Between Eager and Lazy</h3>
<p>Now that we've broken down these two major types of singleton instantiation, it's worthy of note that you'll need to be intentional while deciding whether to create a singleton the eager or lazy way. Your use case/context should help you determine what singleton pattern you need to apply during object creation.</p>
<p>As an engineer, you need to ask yourself these questions when using a singleton for object creation:</p>
<ol>
<li><p>Do I need this class instantiated when the app loads?</p>
</li>
<li><p>Based on the user journey, will this class always be needed during every session?</p>
</li>
<li><p>Can a user journey be completed without needing to call any logic in this class?</p>
</li>
</ol>
<p>These three questions will determine what pattern (eager or lazy) you should use to fulfill best practices while maintaining scalability and high performance in your application.</p>
<h2 id="heading-factory-constructors-in-the-singleton-pattern">Factory Constructors in the Singleton Pattern</h2>
<p>Applying factory constructors in the Singleton pattern can be powerful if you use them properly. But first, let's understand what factory constructors are.</p>
<h3 id="heading-what-are-factory-constructors">What Are Factory Constructors?</h3>
<p>A factory constructor in Dart is a special type of constructor that doesn't always create a new instance of its class. Unlike regular constructors that must return a new instance, factory constructors can:</p>
<ol>
<li><p>Return an existing instance (perfect for singletons)</p>
</li>
<li><p>Return a subclass instance</p>
</li>
<li><p>Apply logic before deciding what to return</p>
</li>
<li><p>Perform validation or initialization before returning an object</p>
</li>
</ol>
<p>The <code>factory</code> keyword tells Dart that this constructor has the flexibility to return any instance of the class (or its subtypes), not necessarily a fresh one.</p>
<h3 id="heading-implementing-singleton-with-factory-constructor">Implementing Singleton with Factory Constructor</h3>
<p>This allows you to apply initialization logic while your class instance is being created before returning the instance.</p>
<pre><code class="lang-dart"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FactoryLazySingleton</span> </span>{
  FactoryLazySingleton._internal();
  <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> FactoryLazySingleton _instance = FactoryLazySingleton._internal();

  <span class="hljs-keyword">static</span> FactoryLazySingleton <span class="hljs-keyword">get</span> instance =&gt; _instance;

  <span class="hljs-keyword">factory</span> FactoryLazySingleton() {
    <span class="hljs-comment">// Your logic runs here</span>
    <span class="hljs-built_in">print</span>(<span class="hljs-string">"Factory constructor called"</span>);
    <span class="hljs-keyword">return</span> _instance;
  }
}
</code></pre>
<h4 id="heading-how-the-factory-constructor-singleton-works">How the Factory Constructor Singleton Works</h4>
<p>This implementation combines aspects of both eager and lazy patterns with additional control.</p>
<p>The <code>FactoryLazySingleton._internal()</code> private constructor and <code>static final _instance</code> create an eager singleton. The instance is created immediately when the class loads.</p>
<p>The <code>static get instance</code> provides the traditional singleton access pattern we've seen before.</p>
<p>But the interesting part is the <code>factory FactoryLazySingleton()</code> constructor. This is a public constructor that looks like a normal constructor call, but behaves differently. When you call <code>FactoryLazySingleton()</code>, instead of creating a new instance, it runs whatever logic you've placed inside (in this case, a print statement), then returns the existing <code>_instance</code>.</p>
<p>This pattern is powerful because:</p>
<ol>
<li><p>You can log when someone tries to create an instance</p>
</li>
<li><p>You can validate conditions before returning the instance</p>
</li>
<li><p>You can apply configuration based on parameters passed to the factory</p>
</li>
<li><p>You can choose to return different singleton instances based on conditions</p>
</li>
</ol>
<p>For example, you might have different configuration singletons for development vs production:</p>
<pre><code class="lang-dart"><span class="hljs-keyword">factory</span> FactoryLazySingleton({<span class="hljs-built_in">bool</span> isProduction = <span class="hljs-keyword">false</span>}) {
  <span class="hljs-keyword">if</span> (isProduction) {
    <span class="hljs-comment">// Apply production configuration</span>
    _instance.configure(productionSettings);
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-comment">// Apply development configuration</span>
    _instance.configure(devSettings);
  }
  <span class="hljs-keyword">return</span> _instance;
}
</code></pre>
<h4 id="heading-pros-2">Pros</h4>
<ol>
<li><p>You can add logic before returning an instance</p>
</li>
<li><p>You can cache or reuse the same object</p>
</li>
<li><p>You can dynamically return a subtype if needed</p>
</li>
<li><p>You avoid unnecessary instantiation</p>
</li>
<li><p>You can inject configuration or environment logic</p>
</li>
</ol>
<h4 id="heading-cons-2">Cons</h4>
<ol>
<li><p>Adds slight complexity compared to simple getter access</p>
</li>
<li><p>The factory constructor syntax might confuse developers unfamiliar with the pattern</p>
</li>
<li><p>If overused with complex logic, it can make debugging harder</p>
</li>
<li><p>Can create misleading code where <code>FactoryLazySingleton()</code> looks like it creates a new instance but doesn't</p>
</li>
</ol>
<h2 id="heading-when-not-to-use-a-singleton">When Not to Use a Singleton</h2>
<p>While singletons are powerful, they're not always the right solution. Understanding when to avoid them is just as important as knowing when to use them.</p>
<h3 id="heading-why-singletons-can-be-problematic">Why Singletons Can Be Problematic</h3>
<p>Singletons create global state, which can make your application harder to reason about and test. They introduce tight coupling between components that shouldn't necessarily know about each other, and they can make it difficult to isolate components for unit testing.</p>
<h3 id="heading-scenarios-where-you-should-avoid-singletons">Scenarios Where You Should Avoid Singletons</h3>
<p>Avoid using the Singleton pattern if:</p>
<h4 id="heading-you-need-multiple-independent-instances">You need multiple independent instances</h4>
<p>If different parts of your app need their own separate configurations or states, singletons force you into a one-size-fits-all approach.</p>
<p>For example, if you're building a multi-tenant application where each tenant needs isolated data, a singleton would cause data to bleed between tenants.</p>
<p><strong>Alternative</strong>: Use dependency injection to pass different instances to different parts of your app. Each component receives the specific instance it needs through its constructor or a service locator.</p>
<pre><code class="lang-dart"><span class="hljs-comment">// Instead of singleton</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserRepository</span> </span>{
  <span class="hljs-keyword">final</span> DatabaseConnection db;
  UserRepository(<span class="hljs-keyword">this</span>.db); 
}

<span class="hljs-comment">// Usage</span>
<span class="hljs-keyword">final</span> dbForTenantA = DatabaseConnection(tenantId: <span class="hljs-string">'A'</span>);
<span class="hljs-keyword">final</span> dbForTenantB = DatabaseConnection(tenantId: <span class="hljs-string">'B'</span>);
<span class="hljs-keyword">final</span> repoA = UserRepository(dbForTenantA);
<span class="hljs-keyword">final</span> repoB = UserRepository(dbForTenantB);
</code></pre>
<h4 id="heading-your-architecture-avoids-shared-global-state">Your architecture avoids shared global state</h4>
<p>Modern architectural patterns like BLoC, Provider, or Riverpod in Flutter specifically aim to avoid global mutable state. Singletons work against these patterns by reintroducing global state.</p>
<p><strong>Alternative</strong>: Use state management solutions designed for Flutter. Provider, Riverpod, BLoC, or GetX offer better ways to share data across your app while maintaining testability and avoiding tight coupling.</p>
<pre><code class="lang-dart"><span class="hljs-comment">// Using Provider instead of singleton</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">AppConfig</span> </span>{
  <span class="hljs-keyword">final</span> <span class="hljs-built_in">String</span> apiUrl;
  AppConfig(<span class="hljs-keyword">this</span>.apiUrl);
}

<span class="hljs-comment">// Provide it at the top level</span>
<span class="hljs-keyword">void</span> main() {
  runApp(
    Provider&lt;AppConfig&gt;(
      create: (_) =&gt; AppConfig(<span class="hljs-string">'https://api.example.com'</span>),
      child: MyApp(),
    ),
  );
}

<span class="hljs-comment">// Access it anywhere in the widget tree</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyWidget</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatelessWidget</span> </span>{
  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">final</span> config = Provider.of&lt;AppConfig&gt;(context);

  }
}
</code></pre>
<h4 id="heading-it-forces-tight-coupling-between-unrelated-classes">It forces tight coupling between unrelated classes</h4>
<p>When multiple unrelated classes depend on the same singleton, they become indirectly coupled. Changes to the singleton affect all these classes, making the codebase fragile and hard to refactor.</p>
<p><strong>Alternative</strong>: Use interfaces and dependency injection. Define what behavior you need through an interface, then inject implementations. This way, classes depend on abstractions, not concrete singletons.</p>
<pre><code class="lang-dart"><span class="hljs-comment">// Define an interface</span>
<span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Logger</span> </span>{
  <span class="hljs-keyword">void</span> log(<span class="hljs-built_in">String</span> message);
}

<span class="hljs-comment">// Implementation</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ConsoleLogger</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Logger</span> </span>{
  <span class="hljs-meta">@override</span>
  <span class="hljs-keyword">void</span> log(<span class="hljs-built_in">String</span> message) =&gt; <span class="hljs-built_in">print</span>(message);
}

<span class="hljs-comment">// Classes depend on the interface, not a singleton</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PaymentService</span> </span>{
  <span class="hljs-keyword">final</span> Logger logger;
  PaymentService(<span class="hljs-keyword">this</span>.logger);

  <span class="hljs-keyword">void</span> processPayment() {
    logger.log(<span class="hljs-string">'Processing payment'</span>);
  }
}

<span class="hljs-comment">// Easy to test with mock</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MockLogger</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Logger</span> </span>{
  <span class="hljs-built_in">List</span>&lt;<span class="hljs-built_in">String</span>&gt; logs = [];
  <span class="hljs-meta">@override</span>
  <span class="hljs-keyword">void</span> log(<span class="hljs-built_in">String</span> message) =&gt; logs.add(message);
}
</code></pre>
<h4 id="heading-you-need-clean-isolated-testing">You need clean, isolated testing</h4>
<p>Singletons maintain state between tests, causing test pollution where one test affects another. This makes tests unreliable and order-dependent.</p>
<p><strong>Alternative</strong>: Use dependency injection and create fresh instances for each test. Most testing frameworks support this pattern, allowing you to inject mocks or fakes easily.</p>
<pre><code class="lang-dart"><span class="hljs-comment">// Testable code</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">OrderService</span> </span>{
  <span class="hljs-keyword">final</span> PaymentProcessor processor;
  OrderService(<span class="hljs-keyword">this</span>.processor);
}

<span class="hljs-comment">// In tests</span>
<span class="hljs-keyword">void</span> main() {
  test(<span class="hljs-string">'processes order successfully'</span>, () {
    <span class="hljs-keyword">final</span> mockProcessor = MockPaymentProcessor();
    <span class="hljs-keyword">final</span> service = OrderService(mockProcessor); 

  });
}
</code></pre>
<h3 id="heading-general-guidelines">General Guidelines</h3>
<p>Use singletons sparingly and only when you truly need exactly one instance of something for the entire application lifecycle. Good candidates include logging systems, application-level configuration, and hardware interface managers.</p>
<p>For most other cases, prefer dependency injection, state management solutions, or simply passing instances where needed. These approaches make your code more flexible, testable, and maintainable.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The Singleton pattern is a powerful creational tool, but like every tool, you should use it strategically.</p>
<p>Overusing singletons can make apps tightly coupled, hard to test, and less maintainable.</p>
<p>But when used correctly, the Singleton pattern helps you save memory, enforce consistency, and control object lifecycle beautifully.</p>
<p>The key is understanding your specific use case and choosing the right implementation approach – whether eager, lazy, or factory-based – that best serves your application's needs while maintaining clean, testable code.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How __proto__, prototype, and Inheritance Actually Work in JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ Have you ever wondered why everything in JavaScript acts like an object? Or how inheritance actually works behind the scenes? What's the difference between __proto__ and prototype? If these questions have crossed your mind, you're not alone. These ar... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-proto-prototype-and-inheritance-actually-work-in-javascript/</link>
                <guid isPermaLink="false">690a2d839d070c31fadbc25e</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ inheritence ]]>
                    </category>
                
                    <category>
                        <![CDATA[ prototypeal-inheritance ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Object Oriented Programming ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Shejan Mahamud ]]>
                </dc:creator>
                <pubDate>Tue, 04 Nov 2025 16:44:51 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1762210692821/651a67f9-cbe5-4f09-b048-957caaa5e1ac.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Have you ever wondered why everything in JavaScript acts like an object? Or how inheritance actually works behind the scenes? What's the difference between <code>__proto__</code> and <code>prototype</code>?</p>
<p>If these questions have crossed your mind, you're not alone. These are some of the most fundamental concepts in JavaScript, yet they often confuse developers.</p>
<p>In this tutorial, we'll demystify prototypes, prototype chains, and inheritance in JavaScript. By the end, you'll understand the "what," "why," and "how" of JavaScript's prototype system.</p>
<h3 id="heading-heres-what-ill-cover">Here’s what I’ll cover:</h3>
<ul>
<li><p><a class="post-section-overview" href="#heading-the-string-method-mystery">The String Method Mystery</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-objects-work-internally">How Objects Work Internally</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-understanding-the-prototype-chain">Understanding the Prototype Chain</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-why-everything-in-javascript-is-an-object">Why Everything in JavaScript is an Object</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-difference-between-proto-and-prototype">The Difference Between <strong>proto</strong> and prototype</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-prototypes-work-with-functions">How Prototypes Work with Functions</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-prototypes-work-with-classes">How Prototypes Work with Classes</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>To get the most out of this tutorial, you should have:</p>
<ul>
<li><p>Basic understanding of JavaScript fundamentals</p>
</li>
<li><p>Familiarity with objects, functions, and classes in JavaScript</p>
</li>
<li><p>Knowledge of how to declare and use variables</p>
</li>
<li><p>Experience working with the <code>new</code> keyword (helpful but not required)</p>
</li>
</ul>
<h2 id="heading-the-string-method-mystery">The String Method Mystery</h2>
<p>Let's start with a simple example that demonstrates something interesting about JavaScript:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> name = <span class="hljs-string">"Shejan Mahamud"</span>;
</code></pre>
<p>After declaring this variable, we can use String methods like:</p>
<pre><code class="lang-javascript">name.toLowerCase(); <span class="hljs-comment">// "shejan mahamud"</span>
name.toUpperCase(); <span class="hljs-comment">// "SHEJAN MAHAMUD"</span>
</code></pre>
<p>This seems normal at first glance, but wait – something unusual is happening. Notice anything odd here? We're using dot notation on a string primitive.</p>
<p>Here's the puzzling part: we know that strings are primitive types in JavaScript, not objects. So how can we use dot notation to access methods? After all, dot notation typically only works with objects.</p>
<p>The answer to this mystery lies in understanding how JavaScript handles primitives and prototypes. But before we get there, let's first look at how objects work internally.</p>
<h2 id="heading-how-objects-work-internally">How Objects Work Internally</h2>
<p>When you create an object in JavaScript like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> info1 = {
  <span class="hljs-attr">fName</span>: <span class="hljs-string">"Shejan"</span>,
  <span class="hljs-attr">lName</span>: <span class="hljs-string">"Mahamud"</span>
};
</code></pre>
<p>JavaScript does something interesting behind the scenes. It automatically adds a hidden property called <code>__proto__</code> to your object. This property points to <code>Object.prototype</code>, which is the prototype of the built-in Object class.</p>
<p>You might wonder: does <code>Object.prototype</code> also have a <code>__proto__</code>? Yes, it does, but its value is <code>null</code>. This is because <code>Object.prototype</code> is at the top of the prototype chain and doesn't inherit from anything else.</p>
<p>Let's look at a more complex example to understand this better:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> info1 = {
  <span class="hljs-attr">fName1</span>: <span class="hljs-string">"Shejan"</span>,
  <span class="hljs-attr">lName1</span>: <span class="hljs-string">"Mahamud"</span>
};

<span class="hljs-keyword">const</span> info2 = {
  <span class="hljs-attr">fName2</span>: <span class="hljs-string">"Boltu"</span>,
  <span class="hljs-attr">lName2</span>: <span class="hljs-string">"Mia"</span>,
  <span class="hljs-attr">__proto__</span>: info1
};

<span class="hljs-keyword">const</span> info3 = {
  <span class="hljs-attr">fName3</span>: <span class="hljs-string">"Habu"</span>,
  <span class="hljs-attr">lName3</span>: <span class="hljs-string">"Mia"</span>,
  <span class="hljs-attr">__proto__</span>: info2
};
</code></pre>
<p>In this example, we've intentionally set the <code>__proto__</code> property for <code>info2</code> and <code>info3</code>. Now here's an interesting question: can we access <code>fName1</code> from <code>info3</code>?</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(info3.fName1); <span class="hljs-comment">// "Shejan"</span>
</code></pre>
<p>Yes, we can! Let's understand how this works.</p>
<h2 id="heading-understanding-the-prototype-chain">Understanding the Prototype Chain</h2>
<p>When you try to access a property on an object, JavaScript follows a specific lookup process:</p>
<ol>
<li><p>First, it searches for the property in the object itself (the base object)</p>
</li>
<li><p>If it doesn't find it there, it looks in the object's <code>__proto__</code></p>
</li>
<li><p>If it still doesn't find it, it continues up the chain, checking each <code>__proto__</code> until it either finds the property or reaches <code>null</code></p>
</li>
</ol>
<p>In our example with <code>info3.fName1</code>:</p>
<ul>
<li><p>JavaScript first looks in <code>info3</code> – and it doesn't find <code>fName1</code></p>
</li>
<li><p>Then it checks <code>info3.__proto__</code>, which points to <code>info2</code> – it doesn't find <code>fName1</code> there, either</p>
</li>
<li><p>Next it checks <code>info2.__proto__</code>, which points to <code>info1</code> – and it finds <code>fName1</code> here!</p>
</li>
</ul>
<p>This is called the <strong>prototype chain</strong>, and this is how inheritance works in JavaScript. Here's a visual representation:</p>
<pre><code class="lang-javascript">┌────────────┐
│  info3     │
│ fName3     │
│ lName3     │
└────┬───────┘
     │ __proto__
     ▼
┌────────────┐
│  info2     │
│ fName2     │
│ lName2     │
└────┬───────┘
     │ __proto__
     ▼
┌────────────┐
│  info1     │
│ fName1     │
│ lName1     │
└────┬───────┘
     │ __proto__
     ▼
┌─────────────────┐
│ <span class="hljs-built_in">Object</span>.prototype│
└────┬────────────┘
     ▼
    <span class="hljs-literal">null</span>
</code></pre>
<p>Each object points to the next object in the chain through its <code>__proto__</code> property. This chain continues until it reaches <code>null</code>.</p>
<h2 id="heading-why-everything-in-javascript-is-an-object">Why Everything in JavaScript is an Object</h2>
<p>Now let's solve the mystery we started with: how can primitive types use object methods?</p>
<p>In JavaScript, almost everything behaves like an object, even though primitive types (like strings, numbers, and booleans) technically aren't objects. This works through a process called <strong>auto-boxing</strong> or <strong>wrapper objects</strong>.</p>
<p>Let's see this in action:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> yourName = <span class="hljs-string">"Boltu"</span>;
</code></pre>
<p>When you try to use a method on this string:</p>
<pre><code class="lang-javascript">yourName.toLowerCase();
</code></pre>
<p>Here's what JavaScript does behind the scenes:</p>
<ol>
<li><p>It temporarily wraps the primitive value in a wrapper object: <code>new String("Boltu")</code></p>
</li>
<li><p>This temporary object's <code>__proto__</code> automatically points to <code>String.prototype</code></p>
</li>
<li><p>The method is found in <code>String.prototype</code> and executed</p>
</li>
<li><p>After the operation completes, the wrapper object is discarded</p>
</li>
<li><p><code>yourName</code> returns to being a simple primitive value</p>
</li>
</ol>
<p>This is why you can use methods on primitives even though they're not objects. JavaScript creates a temporary object, uses it to access the method, then throws it away.</p>
<p>The same process happens with other primitive types:</p>
<ul>
<li><p>Numbers use <code>Number.prototype</code></p>
</li>
<li><p>Booleans use <code>Boolean.prototype</code></p>
</li>
</ul>
<p>And so on. This elegant system is why developers often say "everything in JavaScript is an object" – even when it's not technically true, it behaves that way when needed.</p>
<h2 id="heading-the-difference-between-proto-and-prototype">The Difference Between <code>__proto__</code> and <code>prototype</code></h2>
<p>This is one of the most confusing aspects of JavaScript for many developers. Let's break it down clearly.</p>
<h3 id="heading-what-is-prototype">What is <code>prototype</code>?</h3>
<p>When you create a function or class in JavaScript, the language automatically creates a blueprint object called <code>prototype</code>. This happens behind the scenes.</p>
<p>Here's an example:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Person</span>(<span class="hljs-params">name</span>) </span>{
  <span class="hljs-built_in">this</span>.name = name;
}
</code></pre>
<p>When JavaScript sees this function, it internally does this:</p>
<pre><code class="lang-javascript">Person.prototype = { 
  <span class="hljs-attr">constructor</span>: Person 
};
</code></pre>
<p>The <code>Person</code> function now has a hidden property called <code>prototype</code>, which is an object containing a <code>constructor</code> property.</p>
<p>You can add methods to this prototype object:</p>
<pre><code class="lang-javascript">Person.prototype.sayHi = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Hi, I'm "</span> + <span class="hljs-built_in">this</span>.name);
};
</code></pre>
<h3 id="heading-what-is-proto">What is <code>__proto__</code>?</h3>
<p><code>__proto__</code> is a property that exists on every object instance (arrays, functions, objects – everything). It's an internal reference or pointer that indicates which prototype the object inherits from.</p>
<p>By default, when you create an object, its <code>__proto__</code> points to <code>Object.prototype</code>.</p>
<h3 id="heading-how-they-work-together">How They Work Together</h3>
<p>When you use the <code>new</code> keyword:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> p1 = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"Shejan"</span>);
</code></pre>
<p>JavaScript performs these steps internally:</p>
<ol>
<li><p>Creates a new empty object: <code>p1 = {}</code></p>
</li>
<li><p>Sets the object's <code>__proto__</code>: <code>p1.__proto__ = Person.prototype</code></p>
</li>
<li><p>Calls the constructor function with the new object: <code>Person.call(p1, "Shejan")</code></p>
</li>
<li><p>Returns the object: <code>return p1</code></p>
</li>
</ol>
<p>Now when you try to access a method:</p>
<pre><code class="lang-javascript">p1.sayHi(); <span class="hljs-comment">// "Hi, I'm Shejan"</span>
</code></pre>
<p>JavaScript looks for <code>sayHi</code> in <code>p1</code> first. When it doesn't find it, it checks <code>p1.__proto__</code>, which points to <code>Person.prototype</code>, where the method is defined.</p>
<p>The relationship can be expressed as:</p>
<pre><code class="lang-javascript">p1.__proto__ === Person.prototype; <span class="hljs-comment">// true</span>
Person.prototype.constructor === Person; <span class="hljs-comment">// true</span>
</code></pre>
<p><strong>In summary:</strong></p>
<ul>
<li><p><code>prototype</code> is a property of functions/classes that serves as a blueprint for instances</p>
</li>
<li><p><code>__proto__</code> is a property of object instances that points to the prototype they inherit from</p>
</li>
</ul>
<h2 id="heading-how-prototypes-work-with-functions">How Prototypes Work with Functions</h2>
<p>Let's see a complete example with functions:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Person</span>(<span class="hljs-params">name, age</span>) </span>{
  <span class="hljs-built_in">this</span>.name = name;
  <span class="hljs-built_in">this</span>.age = age;
}

<span class="hljs-comment">// Adding a method to the prototype</span>
Person.prototype.introduce = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Hi, I'm <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> and I'm <span class="hljs-subst">${<span class="hljs-built_in">this</span>.age}</span> years old.`</span>);
};

<span class="hljs-comment">// Creating instances</span>
<span class="hljs-keyword">const</span> person1 = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"Alice"</span>, <span class="hljs-number">25</span>);
<span class="hljs-keyword">const</span> person2 = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"Bob"</span>, <span class="hljs-number">30</span>);

person1.introduce(); <span class="hljs-comment">// "Hi, I'm Alice and I'm 25 years old."</span>
person2.introduce(); <span class="hljs-comment">// "Hi, I'm Bob and I'm 30 years old."</span>

<span class="hljs-comment">// Both instances share the same prototype</span>
<span class="hljs-built_in">console</span>.log(person1.__proto__ === Person.prototype); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(person2.__proto__ === Person.prototype); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(person1.__proto__ === person2.__proto__); <span class="hljs-comment">// true</span>
</code></pre>
<p>The key benefit here is memory efficiency: the <code>introduce</code> method exists only once in <code>Person.prototype</code>, but all instances can access it through the prototype chain.</p>
<h2 id="heading-how-prototypes-work-with-classes">How Prototypes Work with Classes</h2>
<p>ES6 introduced the <code>class</code> syntax, which looks different but works the same way under the hood:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> </span>{
  <span class="hljs-keyword">constructor</span>(name) {
    <span class="hljs-built_in">this</span>.name = name;
  }

  sayHi() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Hi, I'm <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>);
  }
}

<span class="hljs-keyword">const</span> user1 = <span class="hljs-keyword">new</span> User(<span class="hljs-string">"Charlie"</span>);
user1.sayHi(); <span class="hljs-comment">// "Hi, I'm Charlie"</span>

<span class="hljs-comment">// Let's check what's really happening</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-keyword">typeof</span> User); <span class="hljs-comment">// "function"</span>
<span class="hljs-built_in">console</span>.log(User.prototype); <span class="hljs-comment">// { sayHi: f, constructor: f User() }</span>
<span class="hljs-built_in">console</span>.log(user1.__proto__ === User.prototype); <span class="hljs-comment">// true</span>
</code></pre>
<p>Classes are essentially syntactic sugar over JavaScript's prototype-based inheritance. Internally:</p>
<ul>
<li><p>A class is still a constructor function</p>
</li>
<li><p>Methods defined in the class are added to <code>ClassName.prototype</code></p>
</li>
<li><p>Instances created with <code>new</code> have their <code>__proto__</code> set to the class's prototype</p>
</li>
</ul>
<p>This means everything we learned about function prototypes applies to classes as well.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Understanding prototypes and the prototype chain is fundamental to mastering JavaScript. These concepts form the foundation of how JavaScript implements inheritance and object-oriented programming.</p>
<h3 id="heading-key-takeaways">Key Takeaways</h3>
<p>Let's recap what we've learned:</p>
<ol>
<li><p><strong>Every object has</strong> <code>__proto__</code>: This property points to the prototype the object inherits from, enabling the prototype chain lookup mechanism.</p>
</li>
<li><p><strong>Functions and classes have</strong> <code>prototype</code>: This property serves as a blueprint for instances created with the <code>new</code> keyword.</p>
</li>
<li><p><strong>The prototype chain enables inheritance</strong>: When JavaScript can't find a property on an object, it walks up the prototype chain until it finds the property or reaches <code>null</code>.</p>
</li>
<li><p><strong>Primitives use wrapper objects</strong>: Even though primitives aren't objects, JavaScript temporarily wraps them in objects to provide access to methods.</p>
</li>
<li><p><strong>Classes are syntactic sugar</strong>: The modern <code>class</code> syntax is cleaner, but it still uses prototypes under the hood.</p>
</li>
</ol>
<p>JavaScript might seem quirky at first, but once you understand how it works under the hood, you'll appreciate its elegant and flexible design.</p>
<p>Happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn Object-Oriented Programming in TypeScript ]]>
                </title>
                <description>
                    <![CDATA[ Object-Oriented Programming (OOP) is one of the most widely used programming paradigms in software development. But is also one of the most misunderstood. This article will help you gain a solid grasp of OOP in TypeScript by walking you through the l... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-object-oriented-programming-in-typescript/</link>
                <guid isPermaLink="false">682201c8ba77730da04e15a8</guid>
                
                    <category>
                        <![CDATA[ TypeScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Object Oriented Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Lucas ]]>
                </dc:creator>
                <pubDate>Mon, 12 May 2025 14:12:24 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1747058547629/98922409-4eaf-45e5-8721-10c6a1e6e5e4.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Object-Oriented Programming (OOP) is one of the most widely used programming paradigms in software development. But is also one of the most misunderstood.</p>
<p>This article will help you gain a solid grasp of OOP in TypeScript by walking you through the language features that support it, and then showing how these features naturally give rise to the four foundational principles: <strong>inheritance</strong>, <strong>polymorphism</strong>, <strong>encapsulation</strong>, and <strong>abstraction</strong>.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>To get the most out of this article, you should be familiar with:</p>
<ul>
<li><p><strong>JavaScript fundamentals</strong> – variables, functions, objects, and arrays.</p>
</li>
<li><p><strong>Basic TypeScript syntax</strong> – including types and how they differ from plain JavaScript.</p>
</li>
</ul>
<h2 id="heading-table-of-contents"><strong>Table of Contents</strong></h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-to-read-this-article">How to Read This Article</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-typescript-language-features">TypeScript Language Features</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-objects">Objects</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-classes-attributes-and-methods">Classes, Attributes, and Methods</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-interfaces">Interfaces</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-abstract-classes">Abstract Classes</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-object-oriented-programming-principles">Object-Oriented Programming Principles</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-inheritance-superclass-and-subclass">Inheritance – Superclass and Subclass</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-polymorphism">Polymorphism</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-encapsulation">Encapsulation</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-abstraction">Abstraction</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h3 id="heading-how-to-read-this-article">How to Read This Article</h3>
<p>I’ve organized this article into two sections. The first section covers TypeScript language features that enable you to implement Object-Oriented Programming (OOP). The second part discusses concepts derived from these features that lead to the four OOP principles: inheritance, polymorphism, encapsulation, and abstraction.</p>
<p>While many teachers, books, and courses start by explaining these principles, I prefer to start with the language features themselves. The reason is simple: they are formal structures – in other words, concrete. Moreover, throughout the article, you'll notice that the OOP principles naturally emerge when you use the language structure correctly.</p>
<h2 id="heading-typescript-language-features"><strong>TypeScript Language Features</strong></h2>
<p>In this section, we’ll explore TypeScript's features that facilitate OOP implementation. Similar mechanisms exist in other object-oriented languages, such as Java and C#, though they may vary in syntax while preserving the core concepts.</p>
<h3 id="heading-objects"><strong>Objects</strong></h3>
<p>An object is a data type that stores a collection of values organized into key/value pairs. These may include primitive data or other objects.</p>
<p>In the following example, the <code>person</code> object stores various pieces of information, such as the key <code>name</code>, which contains the value <code>"Lucas"</code> of type <code>string</code>, and the <code>address</code> key, which holds another object.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> person = {
  name: <span class="hljs-string">"Lucas"</span>, <span class="hljs-comment">// primitive value of type string</span>
  surname: <span class="hljs-string">"Garcez"</span>,
  age: <span class="hljs-number">28</span>, <span class="hljs-comment">// primitive value of type number</span>
  address: {
    <span class="hljs-comment">// object type containing the keys "city" and "country"</span>
    city: <span class="hljs-string">"Melbourne"</span>,
    country: <span class="hljs-string">"Australia"</span>,
  },
};
</code></pre>
<h3 id="heading-classes-attributes-and-methods"><strong>Classes, Attributes, and Methods</strong></h3>
<p>A class serves as a blueprint for creating objects. It specifies an object's structure and behavior through its attributes and methods. Attributes outline the data structure (keys and value types), whereas methods define the actions that can be performed on those attributes.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Person {
  name: <span class="hljs-built_in">string</span>; <span class="hljs-comment">// attribute</span>
  surname: <span class="hljs-built_in">string</span>; <span class="hljs-comment">// attribute</span>
  age: <span class="hljs-built_in">number</span>; <span class="hljs-comment">// attribute</span>

  <span class="hljs-comment">// constructor method (special method)</span>
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">name: <span class="hljs-built_in">string</span>, surname: <span class="hljs-built_in">string</span>, age: <span class="hljs-built_in">number</span></span>) {
    <span class="hljs-built_in">this</span>.name = name;
    <span class="hljs-built_in">this</span>.surname = surname;
    <span class="hljs-built_in">this</span>.age = age;
  }

  <span class="hljs-comment">// method to obtain the full name: "Lucas Garcez"</span>
  getFullName() {
    <span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> <span class="hljs-subst">${<span class="hljs-built_in">this</span>.surname}</span>`</span>;
  }
}
</code></pre>
<h4 id="heading-constructor-method"><strong>Constructor Method</strong></h4>
<p>The constructor is a special method within a class. It’s automatically invoked when a new object is created. Constructors are responsible for initializing the class attributes with values provided during object creation. In TypeScript, the constructor is defined using the <code>constructor</code> keyword, as you can see in the code above.</p>
<h4 id="heading-instance"><strong>Instance</strong></h4>
<p>An instance refers to an object created from a class. For example, using the class <code>Person</code> mentioned above, you can create an object named <code>lucas</code>. Therefore, <code>lucas</code> is an instance of the class <code>Person</code>. To create an instance of an object in JavaScript or TypeScript, you use the keyword <code>new</code>, as demonstrated below:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> lucas = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"Lucas"</span>, <span class="hljs-string">"Garcez"</span>, <span class="hljs-number">28</span>);
lucas.name; <span class="hljs-comment">// "Lucas"</span>
lucas.getFullName(); <span class="hljs-comment">// "Lucas Garcez"</span>
</code></pre>
<p>It is important to note that you can create multiple objects (instances) from the same class. Although all these objects share the same structure (attributes and methods), they are independent and occupy separate memory spaces within the program.</p>
<p>For instance, when creating a new object:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> maria = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"Maria"</span>, <span class="hljs-string">"Oliveira"</span>, <span class="hljs-number">19</span>);
</code></pre>
<p>You now have a new instance of the <code>Person</code> class that doesn't interfere with the previously created <code>lucas</code> object. Each instance maintains its own values and behaviors, ensuring that manipulating one object doesn't affect the others.</p>
<h3 id="heading-interfaces"><strong>Interfaces</strong></h3>
<p>An interface defines a contract establishing which attributes and methods a class must implement. In TypeScript, this relationship is established using the keyword <code>implements</code>. When a class implements an interface, it must include all the attributes and methods specified by that interface and their respective types.</p>
<p>In the following example, you have a banking system where a customer can have either <code>CurrentAccount</code> or <code>SavingsAccount</code> account. Both options must adhere to the bank’s general account rules defined by the <code>BankAccount</code> interface.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Contract defining the attributes and methods of a bank account</span>
<span class="hljs-keyword">interface</span> BankAccount {
  balance: <span class="hljs-built_in">number</span>;
  deposit(amount: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">void</span>;
  withdraw(amount: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">void</span>;
}

<span class="hljs-keyword">class</span> CurrentAccount <span class="hljs-keyword">implements</span> BankAccount {
  balance: <span class="hljs-built_in">number</span>;
  <span class="hljs-comment">// The class can have other attributes and methods</span>
  <span class="hljs-comment">// beyond those specified in the interface</span>
  overdraftLimit: <span class="hljs-built_in">number</span>;

  deposit(amount: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">this</span>.balance += amount;
  }

  withdraw(amount: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">void</span> {
    <span class="hljs-keyword">if</span> (amount &lt;= <span class="hljs-built_in">this</span>.balance) {
      <span class="hljs-built_in">this</span>.balance -= amount;
    }
  }
}

<span class="hljs-keyword">class</span> SavingsAccount <span class="hljs-keyword">implements</span> BankAccount {
  balance: <span class="hljs-built_in">number</span>;

  deposit(amount: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">void</span> {
    <span class="hljs-comment">// can have different logic from CurrentAccount</span>
    <span class="hljs-comment">// but must respect the method signature,</span>
    <span class="hljs-comment">// i.e., parameters (amount: number) and return type (void)</span>
  }

  withdraw(amount: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">void</span> {
    <span class="hljs-comment">// ...</span>
  }
}
</code></pre>
<h3 id="heading-abstract-classes"><strong>Abstract Classes</strong></h3>
<p>Just like interfaces, abstract classes define a model or contract that other classes must follow. But while an interface only describes the structure of a class without providing implementations, an abstract class can include method declarations and concrete implementations.</p>
<p>Unlike regular classes, though, abstract classes <strong>cannot be instantiated directly</strong> – they exist solely as a base from which other classes can inherit their methods and attributes.</p>
<p>In TypeScript, the <code>abstract</code> keyword is used to define an abstract class. In the following example, you’ll refactor the banking system by replacing the interface with an abstract class to define base behavior for all bank accounts.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Abstract class that serves as the base for any type of bank account</span>
<span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> BankAccount {
  balance: <span class="hljs-built_in">number</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">initialBalance: <span class="hljs-built_in">number</span></span>) {
    <span class="hljs-built_in">this</span>.balance = initialBalance;
  }

  <span class="hljs-comment">// Concrete method (with implementation)</span>
  deposit(amount: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">this</span>.balance += amount;
  }

  <span class="hljs-comment">// Abstract method (must be implemented by subclasses)</span>
  <span class="hljs-keyword">abstract</span> withdraw(amount: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">void</span>;
}

<span class="hljs-keyword">class</span> CurrentAccount <span class="hljs-keyword">extends</span> BankAccount {
  withdraw(amount: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">void</span> {
    <span class="hljs-keyword">const</span> fee = <span class="hljs-number">2</span>; <span class="hljs-comment">// Current accounts have a fixed withdrawal fee</span>
    <span class="hljs-keyword">const</span> totalAmount = amount + fee;

    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.balance &gt;= totalAmount) {
      <span class="hljs-built_in">this</span>.balance -= totalAmount;
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Insufficient balance."</span>);
    }
  }
}

<span class="hljs-keyword">class</span> SavingsAccount <span class="hljs-keyword">extends</span> BankAccount {
  withdraw(amount: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">void</span> {
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.balance &gt;= amount) {
      <span class="hljs-built_in">this</span>.balance -= amount;
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Insufficient balance."</span>);
    }
  }
}

<span class="hljs-comment">// ❌ Error! Cannot instantiate an abstract class</span>
<span class="hljs-keyword">const</span> genericAccount = <span class="hljs-keyword">new</span> BankAccount(<span class="hljs-number">1000</span>); <span class="hljs-comment">// Error</span>

<span class="hljs-comment">// ✅ Creating a current account</span>
<span class="hljs-keyword">const</span> currentAccount = <span class="hljs-keyword">new</span> CurrentAccount(<span class="hljs-number">2000</span>); <span class="hljs-comment">// uses the BankAccount constructor</span>
currentAccount.deposit(<span class="hljs-number">500</span>); <span class="hljs-comment">// uses the deposit method from BankAccount</span>
currentAccount.withdraw(<span class="hljs-number">300</span>); <span class="hljs-comment">// uses the withdraw method from CurrentAccount</span>

<span class="hljs-comment">// ✅ Creating a savings account</span>
<span class="hljs-keyword">const</span> savingsAccount = <span class="hljs-keyword">new</span> SavingsAccount(<span class="hljs-number">1500</span>); <span class="hljs-comment">// uses the BankAccount constructor</span>
savingsAccount.deposit(<span class="hljs-number">1100</span>); <span class="hljs-comment">// uses the deposit method from BankAccount</span>
savingsAccount.withdraw(<span class="hljs-number">500</span>); <span class="hljs-comment">// uses the withdraw method from SavingsAccount</span>
</code></pre>
<h2 id="heading-object-oriented-programming-principles"><strong>Object-Oriented Programming Principles</strong></h2>
<p>Now that you understand the key language mechanisms, you can formalize the pillars of Object-Oriented Programming that guide the creation of systems that are better organized, reusable, and scalable.</p>
<h3 id="heading-inheritance-superclass-and-subclass"><strong>Inheritance – Superclass and Subclass</strong></h3>
<p>Inheritance is a mechanism that allows a class to derive characteristics from another class. When a class <code>B</code> inherits from a class <code>A</code>, it means that <code>B</code> automatically acquires the attributes and methods of <code>A</code> without needing to redefine them.</p>
<p>You can visualize this relationship as a parent-child structure, where <code>A</code> is the superclass (base/parent class) and <code>B</code> is the subclass (derived/child class). A subclass can use inherited resources, add new behaviors, or override superclass methods to address specific needs.</p>
<p>We’ve already discussed inheritance when learning about abstract classes, but inheritance can also be applied to concrete classes. This allows for code reuse and behavior specialization.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// BankAccount is now a regular class where you define attributes and methods</span>
<span class="hljs-comment">// that will be reused by the child class CurrentAccount</span>
<span class="hljs-keyword">class</span> BankAccount {
  balance: <span class="hljs-built_in">number</span> = <span class="hljs-number">0</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">initialBalance: <span class="hljs-built_in">number</span></span>) {
    <span class="hljs-built_in">this</span>.balance = initialBalance;
  }

  deposit(amount: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">this</span>.balance += amount;
  }

  withdraw(amount: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">void</span> {
    <span class="hljs-keyword">if</span> (amount &lt;= <span class="hljs-built_in">this</span>.balance) {
      <span class="hljs-built_in">this</span>.balance -= amount;
    }
  }
}

<span class="hljs-comment">// CurrentAccount is a subclass of BankAccount, meaning </span>
<span class="hljs-comment">// it inherits its attributes and methods.</span>
<span class="hljs-keyword">class</span> CurrentAccount <span class="hljs-keyword">extends</span> BankAccount {
  overdraftLimit: <span class="hljs-built_in">number</span>; <span class="hljs-comment">// new attribute exclusive to CurrentAccount</span>

  <span class="hljs-comment">// When specifying a constructor method for a subclass,</span>
  <span class="hljs-comment">// we need to call another special method, "super".</span>
  <span class="hljs-comment">// This method calls the superclass (BankAccount) constructor to ensure</span>
  <span class="hljs-comment">// it is initialized before creating the CurrentAccount object itself.</span>
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">initialBalance: <span class="hljs-built_in">number</span>, overdraftLimit: <span class="hljs-built_in">number</span></span>) {
    <span class="hljs-built_in">super</span>(initialBalance); <span class="hljs-comment">// Must match the superclass constructor method signature</span>
    <span class="hljs-built_in">this</span>.overdraftLimit = overdraftLimit;
  }

  <span class="hljs-comment">// Even though the withdraw method already exists in the superclass (BankAccount),</span>
  <span class="hljs-comment">// it is overridden here. This means every time a CurrentAccount</span>
  <span class="hljs-comment">// object calls the withdraw method, this implementation will be used, </span>
  <span class="hljs-comment">// ignoring the superclass method.</span>
  override withdraw(amount: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">void</span> {
    <span class="hljs-keyword">const</span> totalAvailable = <span class="hljs-built_in">this</span>.balance + <span class="hljs-built_in">this</span>.overdraftLimit;
    <span class="hljs-keyword">if</span> (amount &gt; <span class="hljs-number">0</span> &amp;&amp; amount &lt;= totalAvailable) {
      <span class="hljs-built_in">this</span>.balance -= amount;
    }
  }
}

<span class="hljs-comment">// Creating a CurrentAccount with an initial balance of $0.00</span>
<span class="hljs-comment">// and an overdraft limit of $100.</span>
<span class="hljs-keyword">const</span> currentAccount = <span class="hljs-keyword">new</span> CurrentAccount(<span class="hljs-number">0</span>, <span class="hljs-number">100</span>);

<span class="hljs-comment">// Making a $200 deposit by calling the deposit method</span>
<span class="hljs-comment">// In this case, the method from BankAccount will be invoked</span>
<span class="hljs-comment">// since deposit was not overridden in CurrentAccount</span>
currentAccount.deposit(<span class="hljs-number">200</span>); <span class="hljs-comment">// balance: 200</span>

<span class="hljs-comment">// Withdrawing $250 by calling the withdraw method</span>
<span class="hljs-comment">// In this case, the method from CurrentAccount will be invoked</span>
<span class="hljs-comment">// as it has been overridden in its definition</span>
currentAccount.withdraw(<span class="hljs-number">250</span>); <span class="hljs-comment">// balance: -50</span>
</code></pre>
<h3 id="heading-polymorphism"><strong>Polymorphism</strong></h3>
<p>Polymorphism is a concept that often creates confusion in Object-Oriented Programming. But in practice, it is merely a natural consequence of using interfaces and inheritance.</p>
<p>The term polymorphism originates from Greek and means "many forms" (poly = many, morphos = forms). This concept allows objects from different classes to respond to the same method call but with distinct implementations, making code more flexible and reusable.</p>
<p>To clarify this concept, let's consider a practical example. Suppose you have a function named <code>sendMoney</code>, responsible for processing a financial transaction, transferring a certain amount from account A to account B. The only requirement is that both accounts follow a common contract, ensuring the methods <code>withdraw</code> and <code>deposit</code> are available.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// BankAccount could be an interface, a concrete class,</span>
<span class="hljs-comment">// or an abstract class. For the sendMoney function, the specific implementation</span>
<span class="hljs-comment">// does not matter—only that BankAccount includes withdraw and deposit methods.</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sendMoney</span>(<span class="hljs-params">
  sender: BankAccount,
  receiver: BankAccount,
  amount: <span class="hljs-built_in">number</span>
</span>) </span>{
  sender.withdraw(amount);
  receiver.deposit(amount);
}

<span class="hljs-keyword">const</span> lucasAccount = <span class="hljs-keyword">new</span> CurrentAccount(<span class="hljs-number">500</span>, <span class="hljs-number">200</span>);
<span class="hljs-keyword">const</span> mariaAccount = <span class="hljs-keyword">new</span> SavingsAccount(<span class="hljs-number">300</span>);

<span class="hljs-comment">// transferring $100 from Lucas to Maria</span>
sendMoney(lucasAccount, mariaAccount, <span class="hljs-number">100</span>);
</code></pre>
<h4 id="heading-polymorphic-methods"><strong>Polymorphic Methods:</strong></h4>
<p>The <code>withdraw</code> and <code>deposit</code> methods are called within the <code>sendMoney</code> function without requiring the function to know whether it is dealing with a <code>CurrentAccount</code> or <code>SavingsAccount</code>. Each class implements <code>withdraw</code> according to its own rules, demonstrating the concept of polymorphism.</p>
<h4 id="heading-decoupling"><strong>Decoupling:</strong></h4>
<p>The <code>sendMoney</code> function does not depend on the specific type of bank account. Any class that extends <code>BankAccount</code> (if it's a class) or implements <code>BankAccount</code> (if it's an interface) can be used without requiring modifications to the <code>sendMoney</code> function.</p>
<p>With this approach, you ensure flexibility and code reusability, as new account types can be introduced without affecting the functionality of <code>sendMoney</code>.</p>
<h3 id="heading-encapsulation"><strong>Encapsulation</strong></h3>
<p>Encapsulation is one of the fundamental principles of OOP, but its concept can be applied to any programming paradigm. It involves hiding the internal implementation details of a module, class, function, or any other software component, exposing only what is necessary for external use. This improves code security, maintainability, and modularity by preventing unauthorized access and ensuring controlled interactions.</p>
<h4 id="heading-access-modifiers-public-private-and-protected"><strong>Access Modifiers –</strong> <code>public</code>, <code>private</code>, and <code>protected</code></h4>
<p>In OOP, encapsulation is essential for controlling the visibility and access to methods and attributes within a class. In TypeScript, this is achieved using access modifiers, which are defined by the keywords <code>public</code>, <code>protected</code>, and <code>private</code>.</p>
<ul>
<li><p><code>public</code> – Allows the attribute or method to be accessed from anywhere, both inside and outside the class. This is the default visibility, meaning that if no access modifier is specified in the code, TypeScript assumes it as <code>public</code>.</p>
</li>
<li><p><code>protected</code> – Allows access within the class and its subclasses but prevents external access.</p>
</li>
<li><p><code>private</code> – Restricts access to the attribute or method only within the class itself.</p>
</li>
</ul>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> Person {
  <span class="hljs-keyword">private</span> firstName: <span class="hljs-built_in">string</span>; <span class="hljs-comment">// Accessible only within the class itself</span>
  <span class="hljs-keyword">private</span> lastName: <span class="hljs-built_in">string</span>; <span class="hljs-comment">// Accessible only within the class itself</span>
  <span class="hljs-keyword">protected</span> birthDate: <span class="hljs-built_in">Date</span>; <span class="hljs-comment">// Accessible by subclasses but not from outside</span>

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">firstName: <span class="hljs-built_in">string</span>, lastName: <span class="hljs-built_in">string</span>, birthDate: <span class="hljs-built_in">Date</span></span>) {
    <span class="hljs-built_in">this</span>.firstName = firstName;
    <span class="hljs-built_in">this</span>.lastName = lastName;
    <span class="hljs-built_in">this</span>.birthDate = birthDate;
  }

  <span class="hljs-comment">// Public method that can be accessed from anywhere</span>
  <span class="hljs-keyword">public</span> getFullName(): <span class="hljs-built_in">string</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.firstName}</span> <span class="hljs-subst">${<span class="hljs-built_in">this</span>.lastName}</span>`</span>;
  }
}

<span class="hljs-comment">// The Professor class inherits from Person and can access</span>
<span class="hljs-comment">// attributes and methods according to their access modifiers.</span>
<span class="hljs-keyword">class</span> Professor <span class="hljs-keyword">extends</span> Person {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">firstName: <span class="hljs-built_in">string</span>, lastName: <span class="hljs-built_in">string</span>, birthDate: <span class="hljs-built_in">Date</span></span>) {
    <span class="hljs-built_in">super</span>(firstName, lastName, birthDate); <span class="hljs-comment">// Calls the superclass (Person) constructor</span>
  }

  getProfile() {
    <span class="hljs-built_in">this</span>.birthDate; <span class="hljs-comment">// ✅ Accessible because it is protected</span>
    <span class="hljs-built_in">this</span>.getFullName(); <span class="hljs-comment">// ✅ Accessible because it is public</span>
    <span class="hljs-built_in">this</span>.firstName; <span class="hljs-comment">// ❌ Error! Cannot be accessed because it is private in the Person class</span>
    <span class="hljs-built_in">this</span>.lastName; <span class="hljs-comment">// ❌ Error! Cannot be accessed because it is private in the Person class</span>
  }
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">// Creating an instance of Professor</span>
  <span class="hljs-keyword">const</span> lucas = <span class="hljs-keyword">new</span> Professor(<span class="hljs-string">"Lucas"</span>, <span class="hljs-string">"Garcez"</span>, <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-string">"1996-02-06"</span>));

  <span class="hljs-comment">// Testing direct access to attributes and methods</span>
  lucas.birthDate; <span class="hljs-comment">// ❌ Error! birthDate is protected and can only be accessed within the class or subclasses</span>
  lucas.getFullName(); <span class="hljs-comment">// ✅ Accessible because it is a public method</span>
  lucas.firstName; <span class="hljs-comment">// ❌ Error! firstName is private and cannot be accessed outside the Person class</span>
  lucas.lastName; <span class="hljs-comment">// ❌ Error! lastName is also private and inaccessible outside the Person class</span>
}
</code></pre>
<h4 id="heading-access-modifiers-table"><strong>Access Modifiers Table</strong></h4>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Modifier</strong></td><td><strong>Access within the class</strong></td><td><strong>Access in subclass</strong></td><td><strong>Access outside the class</strong></td></tr>
</thead>
<tbody>
<tr>
<td><code>public</code></td><td>✅ Yes</td><td>✅ Yes</td><td>✅ Yes</td></tr>
<tr>
<td><code>protected</code></td><td>✅ Yes</td><td>✅ Yes</td><td>❌ No</td></tr>
<tr>
<td><code>private</code></td><td>✅ Yes</td><td>❌ No</td><td>❌ No</td></tr>
</tbody>
</table>
</div><h3 id="heading-abstraction"><strong>Abstraction</strong></h3>
<p>The concept of abstraction frequently causes confusion because its meaning goes beyond the technical context. If you look up the definition of the word in English, the Cambridge Dictionary defines <strong>"abstract"</strong> as:</p>
<blockquote>
<p><em>Something that exists as an idea, feeling, or quality, rather than as a material object.</em></p>
</blockquote>
<p>This definition can be directly applied to OOP: Abstraction represents an idea or concept without going into concrete implementation details.</p>
<p>Many online references describe abstraction as <em>"</em>hiding implementation details<em>,"</em> which can be misleading since this concept is more closely related to encapsulation. In OOP, abstraction does NOT mean hiding details but defining contracts through abstract <strong>classes</strong> and <strong>interfaces</strong>.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Abstraction using interface</span>
<span class="hljs-keyword">interface</span> BankAccountInterface {
  balance: <span class="hljs-built_in">number</span>;
  deposit(amount: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">void</span>;
  withdraw(amount: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">void</span>;
}

<span class="hljs-comment">// Abstraction using class</span>
<span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> BankAccountClass {
  balance: <span class="hljs-built_in">number</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">initialBalance: <span class="hljs-built_in">number</span></span>) {
    <span class="hljs-built_in">this</span>.balance = initialBalance;
  }

  <span class="hljs-comment">// Concrete method (with implementation)</span>
  deposit(amount: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">this</span>.balance += amount;
  }

  <span class="hljs-comment">// Abstract method (must be implemented by subclasses)</span>
  <span class="hljs-keyword">abstract</span> withdraw(amount: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">void</span>;
}
</code></pre>
<p>In the examples above, both <code>BankAccountInterface</code> and <code>BankAccountClass</code> are examples of abstraction as they define contracts that must be implemented by those who use them.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Although learning Object-Oriented Programming isn't easy, I hope this article has helped clarify the OOP fundamentals and advanced topics.</p>
<p>If you want to keep learning TypeScript and OOP, I highly recommend reading Martin Fowler's book <strong>Refactoring: Improving the Design of Existing Code</strong>. This book contains a massive catalog of refactoring techniques, and the second edition has all code examples written in TypeScript, many of which use OOP features and principles mentioned here.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Classes in JavaScript – A Handbook for Beginners ]]>
                </title>
                <description>
                    <![CDATA[ Are you curious about classes in JavaScript but feel a little puzzled about how they work or why you'd even use them? If that's you, then you're definitely in the right place. Lots of developers find classes a bit tricky at first, and honestly, I was... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-classes-in-javascript-handbook/</link>
                <guid isPermaLink="false">67b47d2761b19f350f00901b</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Object Oriented Programming ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Spruce Emmanuel ]]>
                </dc:creator>
                <pubDate>Tue, 18 Feb 2025 12:29:27 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1739878241514/a725b4af-8061-49c2-9575-2aa4096acb74.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Are you curious about classes in JavaScript but feel a little puzzled about how they work or why you'd even use them? If that's you, then you're definitely in the right place. Lots of developers find classes a bit tricky at first, and honestly, I was once there too.</p>
<p>This article is for you if any of these sounds familiar:</p>
<ul>
<li><p>JavaScript is your first programming language.</p>
</li>
<li><p>You are new to, or not entirely comfortable with, Object-Oriented Programming (OOP) principles.</p>
</li>
<li><p>You have primarily used functions for structuring your JavaScript code.</p>
</li>
</ul>
<p>If you're nodding along to any of these, then keep reading.</p>
<p>In this article, we'll take a step-by-step approach, showing you how object-oriented programming is implemented in JavaScript with objects and constructor functions, and clearly illustrate why understanding and using classes will make you a more versatile and effective JavaScript developer, even if you’re used to writing everything in functions. We’ll end everything with a simple to-do app example so you can see how to use classes.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-functions-functions-everywhere-i-turn">Functions, Functions Everywhere I Turn</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-hold-on-a-second-are-we-saying-functions-are-bad-now">Hold on a second. Are we saying functions are bad now?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-wait-what-javascript-has-no-real-classes">Wait, what? JavaScript has no real classes?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-lets-talk-about-objects-in-javascript">Let's talk about objects in JavaScript.</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-constructor-functions-object-blueprintslets-get-practical">Constructor Functions: Object Blueprints—Let's Get Practical</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-constructor-functions-great-for-blueprints-but-memory-waste">Constructor Functions: Great for Blueprints, but... Memory Waste?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-prototypes-to-the-rescue-again-sharing-methods-efficiently">Prototypes to the Rescue (Again): Sharing Methods Efficiently</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-constructor-functions-prototypes-a-powerful-combo">Constructor Functions + Prototypes: A Powerful Combo</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-inheritance-with-constructor-functions-passing-down-the-family-traits-the-constructor-way">Inheritance with Constructor Functions: Passing Down the Family Traits (the Constructor Way)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-enter-es6-classes-syntactic-sugar-for-prototypes">Enter ES6 Classes: Syntactic Sugar for Prototypes</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-es6-classes-class-syntax-prototypes-in-disguise">ES6 Classes: Class Syntax – Prototypes in Disguise</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-whats-next-more-class-features-and-real-world-examples">What’s Next? More Class Features and Real-World Examples</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-functions-functions-everywhere-i-turn">Functions, Functions Everywhere I Turn</h2>
<p>If you started with JavaScript, chances are that you've become really comfortable with functions. They're like the building blocks of everything for you, right? Think about it: if I asked you to write a program to greet someone by name, you'd probably whip up something like this in a flash:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">greetUser</span>(<span class="hljs-params">userName</span>) </span>{
  alert(<span class="hljs-string">"Hello, "</span> + userName + <span class="hljs-string">"!"</span>);
}

greetUser(<span class="hljs-string">"Alice"</span>); <span class="hljs-comment">// Like magic! It greets Alice.</span>
</code></pre>
<p>Okay, let's level up a bit. Imagine that I asked you to write a program that figures out someone's birth year just by knowing their age. If they're 25, you'd want it to tell them '2000' (assuming the current year is 2025).</p>
<p>What would your first thought be? Probably something like, 'Function time!' Am I right? You'd think, 'I'll write a function; it'll take the age, and boom, it'll spit out the birth year.' See?</p>
<p>Function-first thinking. Totally natural in JavaScript. And here's how you might code it:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getBirthYear</span>(<span class="hljs-params">age</span>) </span>{
  <span class="hljs-keyword">const</span> currentYear = <span class="hljs-number">2025</span>; <span class="hljs-comment">//  For this example, let's say it's 2025</span>
  <span class="hljs-keyword">const</span> birthYear = currentYear - age;
  <span class="hljs-keyword">return</span> birthYear;
}
<span class="hljs-built_in">console</span>.log(getBirthYear(<span class="hljs-number">25</span>)); <span class="hljs-comment">// Yep, it logs 2000!</span>
</code></pre>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/Spruce_khalifa/embed/gbOYvvo" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p> </p>
<p>Now, let's make it a bit more complex. What if we want to be a little smarter and make sure the age is actually a valid age? You know, not some crazy string or a negative number. Sticking with our function-loving brains, what's the natural next step? Another function, of course. We'd probably create a <code>validateAge</code> function:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">validateAge</span>(<span class="hljs-params">age</span>) </span>{
  <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> age !== <span class="hljs-string">"number"</span> || age &lt;= <span class="hljs-number">0</span> || age &gt; <span class="hljs-number">120</span>) {
    <span class="hljs-keyword">return</span> <span class="hljs-string">"Invalid age"</span>;
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-keyword">return</span> age; <span class="hljs-comment">//  Age is good to go!</span>
  }
}

<span class="hljs-built_in">console</span>.log(validateAge(<span class="hljs-number">25</span>)); <span class="hljs-comment">//  Output: 25 (valid!)</span>
<span class="hljs-built_in">console</span>.log(validateAge(<span class="hljs-string">"twenty"</span>)); <span class="hljs-comment">//  Output: Invalid age (not a number)</span>
<span class="hljs-built_in">console</span>.log(validateAge(<span class="hljs-number">-5</span>)); <span class="hljs-comment">//  Output: Invalid age (negative)</span>
</code></pre>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/Spruce_khalifa/embed/xbxKYjZ" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p> </p>
<p>See how we're just piling up functions? <code>getBirthYear</code> does one thing, <code>validateAge</code> does another. They're separate little boxes of code.</p>
<p>Let's push this a little further. What if we also wanted to figure out someone's zodiac sign based on their birth year? Yep, you guessed it—the brain says, 'More functions.' Let's just write another <code>getZodiacSign</code> function:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getZodiacSign</span>(<span class="hljs-params">birthYear</span>) </span>{
    <span class="hljs-keyword">const</span> signs = [
        <span class="hljs-string">"Monkey"</span>, 
        <span class="hljs-string">"Rooster"</span>, 
        <span class="hljs-string">"Dog"</span>, 
        <span class="hljs-string">"Pig"</span>, 
        <span class="hljs-string">"Rat"</span>,    
        <span class="hljs-string">"Ox"</span>,
        <span class="hljs-string">"Tiger"</span>, 
        <span class="hljs-string">"Rabbit"</span>, 
        <span class="hljs-string">"Dragon"</span>, 
        <span class="hljs-string">"Snake"</span>, 
        <span class="hljs-string">"Horse"</span>, 
        <span class="hljs-string">"Sheep"</span>
    ];
    <span class="hljs-keyword">return</span> signs[birthYear % <span class="hljs-number">12</span>]; <span class="hljs-comment">// Simple modulo trick!</span>
}
</code></pre>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/Spruce_khalifa/embed/RNwbQxg" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p> </p>
<p>Are you noticing the pattern here? For every new thing we want to do we're just adding more <em>and</em> more separate functions. Things are starting to feel a <em>bit...</em> scattered, right? And we're not even done adding features.</p>
<p>Okay, now let's say we want to store even more information about a person—their name, country, profession, besides just age. How would we manage all this with our function-centric approach? Well, we might try to create a big 'Person' function that takes all this info:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Person</span>(<span class="hljs-params">name, age, country, profession</span>) </span>{
  <span class="hljs-keyword">const</span> personName = name;
  <span class="hljs-keyword">const</span> personAge = age;
  <span class="hljs-keyword">const</span> personCountry = country;
  <span class="hljs-keyword">const</span> personProfession = profession;

  <span class="hljs-keyword">const</span> validatedAge = validateAge(personAge);
  <span class="hljs-keyword">const</span> birthYear = getBirthYear(validatedAge);
  <span class="hljs-keyword">const</span> zodiacSign = getZodiacSign(birthYear);

  alert(
    <span class="hljs-string">`<span class="hljs-subst">${personName}</span>, you're <span class="hljs-subst">${personAge}</span> years old, born in <span class="hljs-subst">${birthYear}</span>, zodiac sign: <span class="hljs-subst">${zodiacSign}</span>!`</span>
  );
}
</code></pre>
<p>What if we then want to use the person's name in our other functions, like <code>getZodiacSign</code> or <code>getBirthYear</code>? We'd have to go back and manually add <code>name</code> as an argument to each of those functions. Imagine having to update every function whenever you add a new piece of person information.</p>
<pre><code class="lang-js"><span class="hljs-comment">//  Suddenly, we need 'name' everywhere!</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getZodiacSign</span>(<span class="hljs-params">birthYear, name</span>) </span>{
  alert(<span class="hljs-string">"Zodiac sign for "</span> + name + <span class="hljs-string">" is..."</span>);
  <span class="hljs-comment">//... rest of zodiac logic...</span>
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getBirthYear</span>(<span class="hljs-params">age, name</span>) </span>{
  alert(<span class="hljs-string">"Birth year for "</span> + name + <span class="hljs-string">" is..."</span>);
  <span class="hljs-comment">// ... rest of birth year logic...</span>
}
</code></pre>
<p>In this tiny example, it's sort of manageable. But picture a huge project with tons of functions spread across files and folders, how you’d try to keep everything in sync and update functions whenever your <code>person</code> data changes. That sounds like a recipe for headaches, bugs, and a lot of frustration. It can become incredibly inefficient and, honestly, pretty error-prone.</p>
<h2 id="heading-hold-on-a-second-are-we-saying-functions-are-bad-now">Hold on a second. Are we saying functions are bad now?</h2>
<p>Functions are amazing. Think of this function-focused approach as the 'classic JavaScript way' of doing things. If you started with JavaScript, this probably feels totally natural and comfortable—and that's great. Even super popular modern libraries like React are built using functions for components. Functions are incredibly powerful and flexible.</p>
<p>But, even in React, if you change some core data (like a 'prop' in React terms) in a main component, you might have to go digging through lots of other components to make sure everything still works smoothly. Functions are fantastic, but sometimes, for certain kinds of problems, there might be another way to organize our code. A way that, for some folks, feels more intuitive, especially if they come from other programming backgrounds.</p>
<p>Imagine asking a programmer whose first language was Java or C++ to build our <code>birth year</code> program. Their brain might light up, but they'd probably think something a bit different. Maybe something like this:</p>
<p>'We need a <code>Person(class)</code>. A <code>Person</code> has an <code>age(proterty)</code> and we need a way to <code>calculateBirthYear(action)</code> for a <code>Person</code>.'</p>
<p>Notice anything different? Functions aren't the first thing that jumps to their mind. It's more about <code>objects</code> and <code>things</code> having <code>properties</code> and <code>actions</code>. Mind-blowing, huh? Many programmers who started with languages like Java or C++ naturally think in this object-oriented (or OOP) style. And hey, maybe that's why you're reading this—maybe you're curious about exploring this object-thinking approach too, especially in JavaScript. Don't worry, I’m not asking you to suddenly switch to Java 😉.</p>
<p>So, about these classes in JavaScript. Get ready for a little JavaScript twist. Here's the thing: JavaScript technically doesn't have classes in the way languages like Java or C++ do. I know, it can be a bit of a head-scratcher. Instead of classical classes as found in languages like Java or C++, JavaScript is built on something called prototypes*.* It uses these flexible prototypes and objects to mimic how classes work in other languages. So, if you want to use classes in JavaScript effectively, the real key is to understand objects and prototypes first. That's where the magic is in JavaScript OOP.</p>
<h2 id="heading-wait-what-javascript-has-no-real-classes">Wait, what? JavaScript has no real classes?</h2>
<p>Does that mean we are stuck with just functions forever? Nope. Even though JavaScript does things its own way with prototypes (instead of classic classes), it still fully supports 'Object-Oriented Programming' (OOP).</p>
<p>Let's break down OOP in plain English. Two big ideas in OOP are <strong>Encapsulation</strong> and <strong>Inheritance</strong>. Sounds fancy, right? But they're actually pretty simple concepts.</p>
<p>Encapsulation? Imagine a capsule, like for medicine. You're just bundling things that belong together. In OOP, encapsulation means grouping data (like age, name) and the actions you can do with that data (like calculate birth year, greet) inside a single 'object'. JavaScript objects are perfect for this.</p>
<p>And inheritance? Think of it like inheriting traits from your family. In JavaScript OOP, objects can 'inherit' properties and behaviors from other objects. JavaScript calls this prototypal inheritance, and the object you inherit from is called the prototype (we'll dive deeper into prototype soon).</p>
<p>See? No function jail here. JavaScript is totally ready for OOP. To see this in action, let's rewrite our birth year program, but this time using this OOP style in JavaScript.</p>
<p>Check this out. Here's how we could rewrite our birth year program using an OOP style in JavaScript, using just a good old JavaScript object:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> Person = {
  <span class="hljs-comment">//  --- Properties (Data) ---</span>
  <span class="hljs-attr">name</span>: <span class="hljs-string">"Spruce"</span>,
  <span class="hljs-attr">age</span>: <span class="hljs-number">25</span>,
  <span class="hljs-attr">country</span>: <span class="hljs-string">"Nigeria"</span>,
  <span class="hljs-attr">profession</span>: <span class="hljs-string">"Engineer"</span>,

  <span class="hljs-comment">//  --- Methods (Actions related to Person data) ---</span>
  <span class="hljs-attr">isValidAge</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">typeof</span> <span class="hljs-built_in">this</span>.age === <span class="hljs-string">"number"</span> &amp;&amp; <span class="hljs-built_in">this</span>.age &gt; <span class="hljs-number">0</span>;
  },

  <span class="hljs-attr">getBirthYear</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">this</span>.isValidAge()) {
      <span class="hljs-keyword">return</span> <span class="hljs-string">"Invalid age!"</span>;
    }
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().getFullYear() - <span class="hljs-built_in">this</span>.age;
  },

  <span class="hljs-attr">getZodiacSign</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">this</span>.isValidAge()) {
      <span class="hljs-keyword">return</span> <span class="hljs-string">"Oops, can't get zodiac for an invalid age!"</span>;
    }

    <span class="hljs-keyword">const</span> birthYear = <span class="hljs-built_in">this</span>.getBirthYear();
    <span class="hljs-keyword">const</span> zodiacSigns = [
      <span class="hljs-string">"Capricorn"</span>,
      <span class="hljs-string">"Aquarius"</span>,
      <span class="hljs-string">"Pisces"</span>,
      <span class="hljs-string">"Aries"</span>,
      <span class="hljs-string">"Taurus"</span>,
      <span class="hljs-string">"Gemini"</span>,
      <span class="hljs-string">"Cancer"</span>,
      <span class="hljs-string">"Leo"</span>,
      <span class="hljs-string">"Virgo"</span>,
      <span class="hljs-string">"Libra"</span>,
      <span class="hljs-string">"Scorpio"</span>,
      <span class="hljs-string">"Sagittarius"</span>,
    ];
    <span class="hljs-keyword">return</span> zodiacSigns[birthYear % <span class="hljs-number">12</span>];
  },

  <span class="hljs-attr">greet</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> (
      <span class="hljs-string">`Hello, I'm <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>. I'm <span class="hljs-subst">${
        <span class="hljs-built_in">this</span>.age
      }</span> years old, born in <span class="hljs-subst">${<span class="hljs-built_in">this</span>.getBirthYear()}</span>, `</span> +
      <span class="hljs-string">`working as a <span class="hljs-subst">${<span class="hljs-built_in">this</span>.profession}</span> from <span class="hljs-subst">${
        <span class="hljs-built_in">this</span>.country
      }</span>.  My zodiac sign is <span class="hljs-subst">${<span class="hljs-built_in">this</span>.getZodiacSign()}</span>.`</span>
    );
  },
};

<span class="hljs-comment">//  --- Let's use our Person object! ---</span>
<span class="hljs-built_in">console</span>.log(Person.greet());
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-comment">//  Output (might vary slightly depending on year):</span>

<span class="hljs-comment">// "Hello, I'm Spruce. I'm 25 years old, born in 2000, working as a Engineer from Nigeria.  My zodiac sign is Pig."</span>
</code></pre>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/Spruce_khalifa/embed/mydbXKq" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p> </p>
<p>See how neat that is? Everything about a <code>Person</code>, their details (name, age, and so on) and what you can do with a person (validate age, get birth year, greet) is all bundled together, and nicely organized inside this single <code>Person</code> object. That's encapsulation in action. Pretty cool, right?</p>
<p>Now, want to know the <code>Person</code> name? Super easy:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(Person.name); <span class="hljs-comment">// Output: "Spruce"</span>
</code></pre>
<p>Birth year? Piece of cake:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(Person.getBirthYear()); <span class="hljs-comment">// Output (if current year is 2025): 2000</span>
</code></pre>
<p>And here's the real magic of encapsulation: if we change something inside the <code>Person</code> object (like, say, we decide to change the age), all the methods (actions) inside automatically adapt. We don't have to go hunting around in separate functions to update things. Let me show you:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//  Age is 25 initially...</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Birth year when age is 25:"</span>, Person.getBirthYear()); <span class="hljs-comment">// Output (if current year is 2025): 2000</span>

<span class="hljs-comment">//  Let's update the age directly in the Person object...</span>
Person.age = <span class="hljs-number">30</span>;

<span class="hljs-comment">//  Now, getBirthYear automatically uses the *new* age!</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Birth year when age is 30:"</span>, Person.getBirthYear()); <span class="hljs-comment">// Output (if current year is 2025): 1995</span>
</code></pre>
<p>So, JavaScript uses objects—and, as we'll see, prototypes—to bring OOP to life, even if it doesn't have classic classes. Hopefully, you're starting to see the appeal of organizing code this way. Before we jump into classes, it makes a ton of sense to get a really solid understanding of objects and prototypes in JavaScript, right? That's what we'll dive into next.</p>
<h2 id="heading-lets-talk-about-objects-in-javascript">Let's talk about objects in JavaScript.</h2>
<p>If you're already familiar with how objects work, that's fantastic. It'll make understanding everything we cover in this article even smoother. To make sure we're all on the same page, let's start with a super basic object:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> Person = {};
</code></pre>
<p>So, is <code>Person</code> an empty object? At first glance, it certainly looks empty. If you thought "yes," you're not alone. It's a common initial thought. But in JavaScript, objects are a little more interesting than just what we explicitly put into them. Let's explore how objects really work under the hood.</p>
<h3 id="heading-okay-so-how-do-objects-work-in-javascript">Okay, so how do objects work in JavaScript?</h3>
<p>Let's break it down. At its core, an object is a collection of properties. Think of properties as named containers for values. Each property has a name (also called a 'key').</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> Person = {
  <span class="hljs-attr">firstName</span>: <span class="hljs-string">"John"</span>,
  <span class="hljs-attr">lastName</span>: <span class="hljs-string">"Doe"</span>,
};
</code></pre>
<p><code>firstName</code> and <code>lastName</code> are the property names (keys), and <code>"John"</code> and <code>"Doe"</code> are their respective values. A property in an object is always a key-value pair. The value part can be many things.</p>
<p>The value associated with a property can be a primitive data type. In JavaScript, primitives are things like strings, numbers, booleans (<code>true</code> or <code>false</code>), <code>null</code>, <code>undefined</code>, and symbols. Let's see some examples:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> exampleObject = {
  <span class="hljs-attr">name</span>: <span class="hljs-string">"Example"</span>, <span class="hljs-comment">// String</span>
  <span class="hljs-attr">age</span>: <span class="hljs-number">30</span>, <span class="hljs-comment">// Number</span>
  <span class="hljs-attr">isStudent</span>: <span class="hljs-literal">false</span>, <span class="hljs-comment">// Boolean</span>
  <span class="hljs-attr">favoriteColor</span>: <span class="hljs-literal">null</span>, <span class="hljs-comment">// null</span>
};
</code></pre>
<p>But the cool thing is, property values can also be more complex data types or even other objects, functions, and arrays. Let's look at that:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> anotherObject = {
  <span class="hljs-attr">address</span>: {
    <span class="hljs-comment">// Value is another object</span>
    <span class="hljs-attr">street</span>: <span class="hljs-string">"123 Main St"</span>,
    <span class="hljs-attr">city</span>: <span class="hljs-string">"Anytown"</span>,
  },
  <span class="hljs-attr">hobbies</span>: [<span class="hljs-string">"reading"</span>, <span class="hljs-string">"hiking"</span>], <span class="hljs-comment">// Value is an array</span>
  <span class="hljs-attr">greet</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// Value is a function (a method!)</span>
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Hello!"</span>);
  },
};
</code></pre>
<p>When a function is a property of an object, we call it a method. It's essentially a function that belongs to the object and usually operates on the object's data.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> calculator = {
  <span class="hljs-attr">value</span>: <span class="hljs-number">0</span>,
  <span class="hljs-attr">add</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">number</span>) </span>{
    <span class="hljs-built_in">this</span>.value += number; <span class="hljs-comment">// 'this' refers to the calculator object</span>
  },
  <span class="hljs-attr">getValue</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.value;
  }
};

calculator.add(<span class="hljs-number">5</span>);
<span class="hljs-built_in">console</span>.log(calculator.getValue()); <span class="hljs-comment">// Output: 5</span>
</code></pre>
<p>Now, here’s where things get really interesting. Objects in JavaScript don't just have the properties we explicitly define. They can also reference properties from other objects. This is a core concept called prototypal inheritance (sometimes just called prototypal delegation).</p>
<p>Remember our seemingly empty <code>Person = {}</code> object? We said it looked empty, right? Well, it's time for a bit of JavaScript magic. Even though we didn't put any properties in it ourselves, it's not completely empty. Every object in JavaScript, by default, has a hidden link (often referred to internally as its [[Prototype]] property) to another object called its prototype.</p>
<p>For objects created using the simple <code>{}</code> syntax (like our <code>person</code> object), their default prototype is the built-in <code>Object.prototype</code>. Think of <code>Object.prototype</code> as a kind of parent object that provides some basic, built-in functionality to all objects.</p>
<p>This is why you can do things like this, even with our "empty" <code>Person</code> object:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(Person.toString()); <span class="hljs-comment">// Output: [object Object]</span>
</code></pre>
<p>Wait a minute. We never defined a <code>toString()</code> method in our <code>Person</code> object. So where is it coming from? It's coming from its prototype, <code>Object.prototype</code>. <code>toString()</code> is a method that's built into <code>Object.prototype</code>, and because <code>Person's</code> prototype is <code>Object.prototype</code>, <code>Person</code> can access and use the <code>toString()</code> method.</p>
<p>So, a good way to think about it is: "The prototype of an object is another object from which it can look up and use properties and methods if it doesn't have them itself."</p>
<p>Why is understanding prototypes so important? Because it unlocks the power of code reuse and creating specialized objects based on more general ones. This is where things get really powerful, especially as your JavaScript projects grow.</p>
<p>Imagine that we want to create a more specific type of <code>Person</code>—say, a <code>Developer</code>. A <code>Developer</code> is still a <code>Person</code>, but they might have some additional properties or behaviors specific to developers. Basically, we want a <code>Developer</code> object to be a <code>Person</code>, but also have its own unique stuff.</p>
<p>This is where we can explicitly set up prototypes. Instead of relying on the default <code>Object.prototype</code>, we can tell JavaScript: "Hey, I want the prototype of my <code>Developer</code> object to be the <code>Person</code> object we already defined." We can do this using <code>Object.create()</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> Person = {
  <span class="hljs-attr">firstName</span>: <span class="hljs-string">"John"</span>,
  <span class="hljs-attr">lastName</span>: <span class="hljs-string">"Doe"</span>,
  <span class="hljs-attr">sayHello</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Hello, my name is <span class="hljs-subst">${<span class="hljs-built_in">this</span>.firstName}</span> <span class="hljs-subst">${<span class="hljs-built_in">this</span>.lastName}</span>`</span>);
  },
};

<span class="hljs-keyword">const</span> developer = <span class="hljs-built_in">Object</span>.create(Person); <span class="hljs-comment">// developer's prototype is now 'Person'</span>
developer.firstName = <span class="hljs-string">"Spruce"</span>; <span class="hljs-comment">// Add a *specific* firstName for developer</span>
developer.programmingLanguage = <span class="hljs-string">"JavaScript"</span>; <span class="hljs-comment">// Developer's own property</span>

developer.sayHello(); <span class="hljs-comment">// Output: Hello, my name is Spruce Person (still accesses sayHello from 'person' prototype!)</span>
<span class="hljs-built_in">console</span>.log(developer.programmingLanguage); <span class="hljs-comment">// Output: JavaScript (developer's own property)</span>
<span class="hljs-built_in">console</span>.log(developer.lastName); <span class="hljs-comment">// Output: Doe (inherited from 'Person' prototype!)</span>
</code></pre>
<p>Let's break down what's happening when we access properties on <code>Developer</code>:"</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(developer.firstName); <span class="hljs-comment">// Output: Spruce (developer's *own* property)</span>
<span class="hljs-built_in">console</span>.log(developer.programmingLanguage); <span class="hljs-comment">// Output: JavaScript (developer's *own* property)</span>
<span class="hljs-built_in">console</span>.log(developer.lastName); <span class="hljs-comment">// Output: Doe (found on the *prototype* 'Person')</span>
<span class="hljs-built_in">console</span>.log(developer.sayHello()); <span class="hljs-comment">// Output: Hello, my name is Spruce Person (method from *prototype*)</span>
<span class="hljs-built_in">console</span>.log(developer.job); <span class="hljs-comment">// Output: undefined (not on 'Developer' OR 'Person' prototype)</span>
</code></pre>
<p>When you try to access a property like <code>Developer.lastName</code>, JavaScript does the following:</p>
<ol>
<li><p>First, it checks: Does <code>Developer</code> have a property named <code>lastName</code> directly on itself? In our example, <code>Developer</code> only has <code>firstName</code> and <code>programmingLanguage</code> as its own properties. <code>lastName</code> is not there.</p>
</li>
<li><p>If it doesn't find it on the object itself, JavaScript then looks at the object's prototype (which we set to <code>Person using</code> <code>Object.create()</code>).</p>
</li>
<li><p>It checks: 'Does the <code>Person</code> object (the prototype) have a property named <code>lastName</code>?' Yes, <code>Person</code> does have <code>lastName: "Doe"</code>. So, JavaScript uses this value.</p>
</li>
<li><p>If the property isn’t found on the prototype either, JavaScript would then look at the <code>Person</code>'s prototype (which is <code>Object.prototype</code> by default), and so on, up the prototype chain. If it goes all the way up the chain and still doesn't find the property, it finally returns <code>undefined</code> (like when we tried to access <code>developer.job</code>).</p>
</li>
</ol>
<p>Own properties are simply the properties that are defined directly on the object itself when you create it (like <code>firstName</code> and <code>programmingLanguage</code> on <code>Developer</code>). Prototype properties are accessed through the prototype chain.</p>
<p>You can even create longer prototype chains. For example, let's say we want to create a <code>JavaScriptDeveloper</code> object, which is a type of <code>Developer</code>. We can make <code>Developer</code> the prototype of <code>JavaScriptDeveloper</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> JavaScriptDeveloper = <span class="hljs-built_in">Object</span>.create(Developer); <span class="hljs-comment">// javaScriptDeveloper's prototype is 'Developer'</span>

JavaScriptDeveloper.framework = <span class="hljs-string">"React"</span>; <span class="hljs-comment">// JavaScriptDeveloper's own property</span>

<span class="hljs-built_in">console</span>.log(JavaScriptDeveloper.firstName); <span class="hljs-comment">// Output: Spruce (from 'Developer' prototype)</span>

<span class="hljs-built_in">console</span>.log(JavaScriptDeveloper.lastName); <span class="hljs-comment">// Output: Doe (from 'Person' prototype)</span>

<span class="hljs-built_in">console</span>.log(JavaScriptDeveloper.programmingLanguage); <span class="hljs-comment">// Output: JavaScript (from 'Developer' prototype)</span>

<span class="hljs-built_in">console</span>.log(JavaScriptDeveloper.framework); <span class="hljs-comment">// Output: React (JavaScriptDeveloper's own property)</span>

<span class="hljs-built_in">console</span>.log(JavaScriptDeveloper.job); <span class="hljs-comment">// Output: undefined (not found anywhere in the chain)</span>
</code></pre>
<p>(Optional Exploration: If you're curious, trace the lookup for <code>javaScriptDeveloper.lastName</code>. It goes: <code>JavaScriptDeveloper</code> -&gt; <code>Developer</code> -&gt; <code>Person</code> -&gt; <code>Object.prototype</code>).</p>
<p>Okay, prototypes are powerful. We can create objects that share properties and behaviors and specialize them for different needs. But imagine if we wanted to create hundreds of <code>Person</code> objects, hundreds of <code>Developer</code> objects, and hundreds of <code>JavaScriptDeveloper</code> objects.</p>
<p>Using <code>Object.create()</code> every time would still be quite repetitive, especially if we want to ensure that every <code>Person</code> starts with the same basic properties (like <code>firstName</code> and <code>lastName</code>).</p>
<p>We need a better way to create multiple objects that follow the same pattern, like a blueprint that we can re-use over and over again to create objects. This is what classes are for, they are just blueprints that we can use to create multiple objects, and JavaScript uses Constructor functions to create classes (the blueprints).</p>
<p>In the next section, we’ll dive into how javascript uses Constructor functions to implement classes.</p>
<h2 id="heading-constructor-functions-object-blueprintslets-get-practical">Constructor Functions: Object Blueprints—Let's Get Practical</h2>
<p>Okay, prototypes are pretty cool for code reuse and making specialized objects. We saw how <code>Object.create()</code> lets us create objects that inherit from others. But imagine that we wanted to make tons of <code>Person</code> objects, like, hundreds of them for a website. Typing out <code>Object.create(person)</code> for every single one would get super repetitive, especially if we always want every <code>Person</code> to start with the same basic properties, like a <code>firstName</code> and <code>lastName</code>.</p>
<p>We need a more efficient way to make lots of objects that follow the same pattern. What we really need is something like a blueprint—something we can use over and over again to stamp out new objects, all looking and working in a similar way. And guess what? That’s exactly what constructor functions are for.</p>
<p>Think of constructor functions as JavaScript's way of creating blueprints for objects. They're like object factories. And in JavaScript, we use constructor functions, which are specialized functions used in a particular way, to create these blueprints. Yep, functions again. But we use them in a special way.</p>
<h3 id="heading-so-what-is-a-constructor-function-exactly">So what is a constructor function, exactly?</h3>
<p>Well, like I said, it's a function that creates objects. Take a look at this example:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">PersonConstructor</span>(<span class="hljs-params">name, age</span>) </span>{
  <span class="hljs-built_in">this</span>.name = name;
  <span class="hljs-built_in">this</span>.age = age;
  <span class="hljs-built_in">this</span>.greet = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Hello, I'm <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>);
  };
}
</code></pre>
<p>That looks like a regular function. You're absolutely right. It looks just like any other function you've probably written in JavaScript. In fact, let's prove it. If we just log <code>PersonConstructor</code> itself, we’ll see:</p>
<pre><code class="lang-js"><span class="hljs-built_in">console</span>.log(PersonConstructor);
</code></pre>
<pre><code class="lang-js"><span class="hljs-comment">// output</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">PersonConstructor</span>(<span class="hljs-params">name, age</span>) </span>{
  <span class="hljs-built_in">this</span>.name = name;
  <span class="hljs-built_in">this</span>.age = age;
  <span class="hljs-built_in">this</span>.greet = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Hello, I'm <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>);
  };
}
</code></pre>
<p>See? Just a regular function. So, what makes it a constructor function?</p>
<h3 id="heading-the-magic-ingredient-the-new-keyword">The Magic Ingredient: The <code>new</code> Keyword</h3>
<p>What turns an ordinary function into a constructor**—**something that builds objects—is the <code>new</code> keyword. It's like saying to JavaScript, "Hey, treat this function as a blueprint, and use it to create a new object for me."</p>
<p>Let's see it in action:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> person1 = <span class="hljs-keyword">new</span> PersonConstructor(<span class="hljs-string">"Alice"</span>, <span class="hljs-number">25</span>);

<span class="hljs-built_in">console</span>.log(person1);
</code></pre>
<pre><code class="lang-js"><span class="hljs-comment">// output</span>

<span class="hljs-comment">// PersonConstructor { name: 'Alice', age: 25, greet: [Function] }</span>
</code></pre>
<p>In the output now, instead of just seeing the function code, we're seeing a <code>PersonConstructor</code> object. The <code>new</code> keyword didn't just call the function, it actually created a brand new object based on the <code>PersonConstructor</code> blueprint.</p>
<p>Now, we can use this blueprint, <code>PersonConstructor</code>, to create as many <code>Person</code> objects as we want, all with the same basic structure:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> person1 = <span class="hljs-keyword">new</span> PersonConstructor(<span class="hljs-string">"Alice"</span>, <span class="hljs-number">25</span>);
<span class="hljs-keyword">const</span> person2 = <span class="hljs-keyword">new</span> PersonConstructor(<span class="hljs-string">"Bob"</span>, <span class="hljs-number">30</span>);
<span class="hljs-keyword">const</span> person3 = <span class="hljs-keyword">new</span> PersonConstructor(<span class="hljs-string">"Charlie"</span>, <span class="hljs-number">28</span>);

<span class="hljs-built_in">console</span>.log(person1);
<span class="hljs-built_in">console</span>.log(person2);
<span class="hljs-built_in">console</span>.log(person3);
</code></pre>
<pre><code class="lang-js"><span class="hljs-comment">// output</span>
PersonConstructor { <span class="hljs-attr">name</span>: <span class="hljs-string">'Alice'</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">25</span>, <span class="hljs-attr">greet</span>: [<span class="hljs-built_in">Function</span>] }
PersonConstructor { <span class="hljs-attr">name</span>: <span class="hljs-string">'Bob'</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">30</span>, <span class="hljs-attr">greet</span>: [<span class="hljs-built_in">Function</span>] }
PersonConstructor { <span class="hljs-attr">name</span>: <span class="hljs-string">'Charlie'</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">28</span>, <span class="hljs-attr">greet</span>: [<span class="hljs-built_in">Function</span>] }
</code></pre>
<p>Cool, right? We have three distinct <code>Person</code> objects, all created from the same <code>PersonConstructor</code> blueprint.</p>
<h3 id="heading-hold-up-whats-this-this-keyword-i-keep-seeing">Hold Up... What's This <code>this</code> Keyword I Keep Seeing?</h3>
<p>You've probably noticed the word <code>this</code> popping up a lot in these code examples, like in <code>this.name</code>, <code>this.age</code>, and <code>this.greet()</code>. And you might be thinking, "What in the JavaScript world is <code>this</code>?"</p>
<p>Don't worry, <code>this</code> can be a bit confusing at first, but it's actually pretty simple once you get the hang of it. Let's break it down with a simple analogy.</p>
<p>Imagine you're describing yourself. You might say, "My name is [Your Name]." In this sentence, "my" refers to you, the person speaking.</p>
<p>In JavaScript objects, <code>this</code> is like "my" or "me." It's a way for an object to refer to itself.</p>
<p>Let's see this with a regular object example first:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> PersonObject = {
  <span class="hljs-attr">name</span>: <span class="hljs-string">"Spruce"</span>,
  <span class="hljs-attr">greet</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Hello, my name is "</span> + PersonObject.name); <span class="hljs-comment">//  Using PersonObject.name directly</span>
  },
};

PersonObject.greet(); <span class="hljs-comment">// Output: Hello, my name is Spruce</span>
</code></pre>
<p>In this <code>PersonObject</code>, inside the <code>greet</code> function, we used <code>PersonObject.name</code> to access the <code>name</code> property. This works perfectly fine. We're directly telling JavaScript to get the <code>name</code> property from the <code>PersonObject</code>. We could use <code>this</code> here too, but let's see why <code>this</code> becomes super helpful, especially in constructor functions.</p>
<p>Now, consider this slightly different version using <code>this</code>:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> PersonObjectThis = {
  <span class="hljs-attr">name</span>: <span class="hljs-string">"Spruce"</span>,
  <span class="hljs-attr">greet</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Hello, my name is "</span> + <span class="hljs-built_in">this</span>.name); <span class="hljs-comment">// Using 'this.name'</span>
  },
};

PersonObjectThis.greet(); <span class="hljs-comment">// Output: Hello, my name is Spruce</span>
</code></pre>
<p>See? It still works the same way. When <code>greet</code> is called on <code>PersonObjectThis</code>, inside the <code>greet</code> function, it automatically refers to <code>PersonObjectThis</code>. So <code>this.name</code> is just a more dynamic way of saying "the <code>name</code> property of this current object."</p>
<h3 id="heading-why-use-this-instead-of-directly-naming-the-object">Why use <code>this</code> instead of directly naming the object?</h3>
<p>Because <code>this</code> is dynamic and context-aware. It always points to the object that is currently calling the method. This becomes essential in constructor functions because constructor functions are designed to create many different objects.</p>
<h3 id="heading-back-to-constructor-functions-what-does-this-mean-there">Back to constructor functions: What does <code>this</code> mean there?</h3>
<p>Let's revisit our <code>PersonConstructor</code>:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">PersonConstructor</span>(<span class="hljs-params">name, age</span>) </span>{
  <span class="hljs-built_in">this</span>.name = name;
  <span class="hljs-built_in">this</span>.age = age;
  <span class="hljs-built_in">this</span>.greet = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Hello, I'm <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>);
  };
}

<span class="hljs-keyword">const</span> person1 = <span class="hljs-keyword">new</span> PersonConstructor(<span class="hljs-string">"Alice"</span>, <span class="hljs-number">25</span>);
<span class="hljs-keyword">const</span> person2 = <span class="hljs-keyword">new</span> PersonConstructor(<span class="hljs-string">"Bob"</span>, <span class="hljs-number">30</span>);
</code></pre>
<p>When we do <code>const person1 = new PersonConstructor("Alice", 25);</code> inside the <code>PersonConstructor</code> function:</p>
<ul>
<li><p><code>this</code> becomes <code>person1</code>. It's as if JavaScript is doing:</p>
<ul>
<li><p><a target="_blank" href="http://person1.name"><code>person1.name</code></a> <code>= "Alice";</code></p>
</li>
<li><p><code>person1.age = 25;</code></p>
</li>
<li><p><code>person1.greet = function() { ... };</code></p>
</li>
</ul>
</li>
</ul>
<p>And when we do <code>const person2 = new PersonConstructor("Bob", 30);</code> inside <code>PersonConstructor</code> again:</p>
<ul>
<li><p><code>this</code> becomes <code>person2</code>. Like JavaScript doing:</p>
<ul>
<li><p><a target="_blank" href="http://person2.name"><code>person2.name</code></a> <code>= "Bob";</code></p>
</li>
<li><p><code>person2.age = 30;</code></p>
</li>
<li><p><code>person2.greet = function() { ... };</code></p>
</li>
</ul>
</li>
</ul>
<p>So, <code>this</code> in a constructor function is like a placeholder that gets filled in with the specific object being created when you use <code>new</code>. It's what lets us create many different objects from the same blueprint.</p>
<h2 id="heading-constructor-functions-great-for-blueprints-but-memory-waste">Constructor Functions: Great for Blueprints, but... Memory Waste?</h2>
<p>Okay, so now that you know how to create object blueprints using constructor functions, and you understand what <code>this</code> does, we can make lots of <code>Person</code> objects.</p>
<p>But there's a little problem lurking in our <code>PersonConstructor</code>:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">PersonConstructor</span>(<span class="hljs-params">name, age</span>) </span>{
  <span class="hljs-built_in">this</span>.name = name;
  <span class="hljs-built_in">this</span>.age = age;
  <span class="hljs-built_in">this</span>.greet = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// 😬 Look at this greet function!</span>
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Hello, I'm <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>);
  };
}

<span class="hljs-keyword">const</span> person1 = <span class="hljs-keyword">new</span> PersonConstructor(<span class="hljs-string">"Alice"</span>, <span class="hljs-number">25</span>);
<span class="hljs-keyword">const</span> person2 = <span class="hljs-keyword">new</span> PersonConstructor(<span class="hljs-string">"Bob"</span>, <span class="hljs-number">30</span>);

<span class="hljs-built_in">console</span>.log(person1, person2);
</code></pre>
<pre><code class="lang-js"><span class="hljs-comment">// output</span>

PersonConstructor {<span class="hljs-attr">name</span>: <span class="hljs-string">"Alice"</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">25</span>, <span class="hljs-attr">greet</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>}

<span class="hljs-title">PersonConstructor</span> </span>{name: <span class="hljs-string">"Bob"</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">30</span>, <span class="hljs-attr">greet</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>}</span>
</code></pre>
<p>Notice the <code>greet</code> function inside the <code>PersonConstructor</code>? Every time we create a new <code>Person</code> object using <code>new PersonConstructor()</code>, we're actually copying the entire <code>greet</code> function to each and every object.</p>
<p>Imagine that we create one thousand <code>Person</code> objects. We'd have a thousand identical <code>greet</code> functions in memory. For a simple <code>greet()</code> function, the memory impact might seem small. However, if you had more complex methods with lots of code, or if you were creating thousands or even millions of objects, duplicating these functions for every single object can become a significant waste of memory.</p>
<p>It also impacts performance as JavaScript has to manage all these duplicated functions. That's a lot of duplicated code, and it's not very memory-efficient, especially if the <code>greet</code> function (or other methods) were more complex.</p>
<h2 id="heading-prototypes-to-the-rescue-again-sharing-methods-efficiently">Prototypes to the Rescue (Again): Sharing Methods Efficiently</h2>
<p>Remember prototypes? We learned that objects can inherit properties and methods from their prototypes. Well, constructor functions have a built-in way to use prototypes to solve this memory-waste problem.</p>
<p>Instead of defining the <code>greet</code> function inside the constructor and thus copying it to every instance, we can add it to the <code>prototype</code> of the <code>PersonConstructor</code> function.</p>
<p>Like this:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">PersonConstructor</span>(<span class="hljs-params">name, age</span>) </span>{
  <span class="hljs-built_in">this</span>.name = name;
  <span class="hljs-built_in">this</span>.age = age;
}

<span class="hljs-comment">//  --- Add the greet method to the PROTOTYPE of PersonConstructor! ---</span>
PersonConstructor.prototype.greet = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Hello, I'm <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>);
};
</code></pre>
<p>Now, the <code>greet</code> method is defined only once on <code>PersonConstructor.prototype</code>. But all objects created with <code>PersonConstructor</code> can still use it. They inherit it from the prototype.</p>
<p>Let's test it:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> person1 = <span class="hljs-keyword">new</span> PersonConstructor(<span class="hljs-string">"Alice"</span>, <span class="hljs-number">25</span>);
<span class="hljs-keyword">const</span> person2 = <span class="hljs-keyword">new</span> PersonConstructor(<span class="hljs-string">"Bob"</span>, <span class="hljs-number">30</span>);

person1.greet(); <span class="hljs-comment">// Output: Hello, I'm Alice  - Still works!</span>
person2.greet(); <span class="hljs-comment">// Output: Hello, I'm Bob    - Still works!</span>

<span class="hljs-built_in">console</span>.log(person1.greet === person2.greet); <span class="hljs-comment">// Output: false - They are NOT the same function object in memory</span>

<span class="hljs-built_in">console</span>.log(person1.__proto__.greet === person2.__proto__.greet); <span class="hljs-comment">// Output: true - But they share the same prototype method!</span>
</code></pre>
<p><code>person1.greet()</code> and <code>person2.greet()</code> still work perfectly. But now, the <code>greet</code> function is not copied for each object. It's shared through the prototype. This is much more efficient, especially when we're dealing with lots of objects and methods.</p>
<h2 id="heading-constructor-functions-prototypes-a-powerful-combo">Constructor Functions + Prototypes: A Powerful Combo</h2>
<p>We've now seen how constructor functions act as blueprints for creating objects, and how using the prototype of a constructor function lets us efficiently share methods among all objects created from that blueprint.</p>
<p>This is a key pattern in JavaScript for creating reusable object structures.</p>
<h3 id="heading-okay-weve-covered-object-creation-and-efficient-methods-but-what-about-inheritance-with-constructor-functions">Okay, we've covered object creation and efficient methods... But what about inheritance with constructor functions?</h3>
<p>What if we want to create a <code>DeveloperPerson</code> blueprint that inherits from our <code>PersonConstructor</code> blueprint? So that <code>DeveloperPerson</code> objects automatically has <code>name</code>, <code>age</code>, and <code>greet</code>, but can also have its own special developer-related properties and methods?</p>
<p>That's where things get a bit more involved with constructor functions, and we'll need to use a special trick called <code>call()</code> to make inheritance work. Let's dive into that next.</p>
<h2 id="heading-inheritance-with-constructor-functions-passing-down-the-family-traits-the-constructor-way">Inheritance with Constructor Functions: Passing Down the Family Traits (the Constructor Way)</h2>
<p>Alright, we're making good progress. We've got constructor functions to create object blueprints, and prototypes to share methods efficiently. But one of the big reasons people use OOP is for inheritance – the idea of creating specialized objects that build upon more general ones.</p>
<p>Think back to our <code>Person</code> and <code>Developer</code> example. A <code>Developer</code> is a <code>Person</code>, right? They have a name, an age, maybe they greet people, but they also have developer-specific properties, like a favorite programming language and the ability to code.</p>
<p>How can we create a <code>DeveloperPersonConstructor</code> blueprint that inherits all the basic <code>PersonConstructor</code> stuff, and then adds its own developer-specific features? With constructor functions, you can use something called <code>call()</code>.</p>
<h3 id="heading-call-the-secret-inheritance-handshake"><code>call()</code>: The Secret Inheritance Handshake</h3>
<p><code>call()</code> is a function method that lets you do something a bit unusual: you can borrow a function from one object and run it in the context of another object. Sounds confusing? Let's simplify.</p>
<p>To illustrate <code>call()</code>, let's consider our <code>PersonConstructor</code>. We want to create a <code>DeveloperPersonConstructor</code> that also sets up <code>name</code> and <code>age</code> in the same way <code>PersonConstructor</code> does, before adding developer-specific properties.</p>
<p>This is where <code>call()</code> comes in. We can use <code>call()</code> to essentially say: "Hey <code>PersonConstructor</code>, run your code, but run it as if you were inside <code>DeveloperPersonConstructor</code>, and set up <code>name</code> and <code>age</code> for this <code>DeveloperPerson</code> object we're currently creating."</p>
<p>Let's see this in code to make it clearer:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">PersonConstructor</span>(<span class="hljs-params">name, age</span>) </span>{
  <span class="hljs-built_in">this</span>.name = name;
  <span class="hljs-built_in">this</span>.age = age;
}

PersonConstructor.prototype.greet = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Hello, I'm <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>);
};

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">DeveloperPersonConstructor</span>(<span class="hljs-params">name, age, programmingLanguage</span>) </span>{
  <span class="hljs-comment">//  --- "Borrow" the PersonConstructor to set up name and age! ---</span>
  PersonConstructor.call(<span class="hljs-built_in">this</span>, name, age); <span class="hljs-comment">//  &lt;--  The magic of 'call()'</span>

  <span class="hljs-comment">// --- Now, add developer-specific properties ---</span>
  <span class="hljs-built_in">this</span>.programmingLanguage = programmingLanguage;
  <span class="hljs-built_in">this</span>.code = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> is coding in <span class="hljs-subst">${<span class="hljs-built_in">this</span>.programmingLanguage}</span>`</span>);
  };
}
</code></pre>
<p>See that line: <a target="_blank" href="http://PersonConstructor.call"><code>PersonConstructor.call</code></a><code>(this, name, age);</code> ? That's the key to inheritance here. Let's break it down:</p>
<ul>
<li><p><a target="_blank" href="http://PersonConstructor.call"><code>PersonConstructor.call</code></a><code>(...)</code>: We're calling the <code>PersonConstructor</code> function, but not in the usual way. We're using <code>.call()</code>.</p>
</li>
<li><p><code>this</code>: The first argument to <code>call()</code> is crucial. It specifies what <code>this</code> should be inside the <code>PersonConstructor</code> function when it runs. Here, we're passing <code>this</code> from <code>DeveloperPersonConstructor</code>. Why? Because we want <code>PersonConstructor</code> to set up <code>name</code> and <code>age</code> on the <code>DeveloperPerson</code> object that's currently being created.</p>
</li>
<li><p><code>name, age</code>: These are the arguments we're passing to the <code>PersonConstructor</code> function itself. So, when <code>PersonConstructor</code> runs (thanks to <code>.call()</code>), it will receive <code>name</code> and <code>age</code> and do what it normally does: set <code>this.name = name</code> and <code>this.age = age</code>. But because <code>this</code> is actually the <code>DeveloperPerson</code> object, it sets these properties on the <code>DeveloperPerson</code> object.</p>
</li>
</ul>
<h3 id="heading-putting-it-all-together-creating-a-developerperson">Putting it all Together: Creating a <code>DeveloperPerson</code></h3>
<p>Now, let's create a <code>DeveloperPerson</code> object and see what happens:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> devPerson1 = <span class="hljs-keyword">new</span> DeveloperPersonConstructor(<span class="hljs-string">"Eve"</span>, <span class="hljs-number">30</span>, <span class="hljs-string">"JavaScript"</span>);

<span class="hljs-built_in">console</span>.log(devPerson1.name); <span class="hljs-comment">// Output: Eve (Inherited from PersonConstructor!)</span>
<span class="hljs-built_in">console</span>.log(devPerson1.age); <span class="hljs-comment">// Output: 30 (Inherited from PersonConstructor!)</span>
devPerson1.greet(); <span class="hljs-comment">// Output: (Oops! Error!)</span>
<span class="hljs-built_in">console</span>.log(devPerson1.programmingLanguage); <span class="hljs-comment">// Output: JavaScript (Developer-specific)</span>
devPerson1.code(); <span class="hljs-comment">// Output: Eve is coding in JavaScript (Developer-specific)</span>
</code></pre>
<p>Notice that <code>devPerson1.name</code> and <code>devPerson1.age</code> are there. <code>DeveloperPersonConstructor</code> borrowed the part of <code>PersonConstructor</code> that sets up those basic properties. And we also have <code>devPerson1.programmingLanguage</code> and <code>devPerson1.code()</code> which are specific to developers.</p>
<h3 id="heading-uh-oh-wheres-greet">Uh Oh! Where's <code>greet()</code>?</h3>
<p>But wait, <code>devPerson1.greet()</code> is throwing an error. Why? Because even though we borrowed the constructor logic from <code>PersonConstructor</code>, we haven't yet set up the prototype chain for inheritance of prototype methods like <code>greet()</code>.</p>
<p>Right now, <code>devPerson1</code>'s prototype is just the default object prototype (<code>Object.prototype</code>). It's not inheriting from <code>PersonConstructor.prototype</code>. We need to fix that.</p>
<h3 id="heading-setting-the-prototype-chain-for-constructor-inheritance">Setting the Prototype Chain for Constructor Inheritance</h3>
<p>To make <code>DeveloperPersonConstructor</code> objects also inherit prototype methods from <code>PersonConstructor</code>, we need to manually adjust the prototype chain. We can do this using <code>Object.create()</code> again.</p>
<p>We want the prototype of <code>DeveloperPersonConstructor</code> to be an object that inherits from <code>PersonConstructor.prototype</code>.</p>
<p>Here's the code:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">PersonConstructor</span>(<span class="hljs-params">name, age</span>) </span>{
  <span class="hljs-built_in">this</span>.name = name;
  <span class="hljs-built_in">this</span>.age = age;
}

PersonConstructor.prototype.greet = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Hello, I'm <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>);
};

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">DeveloperPersonConstructor</span>(<span class="hljs-params">name, age, programmingLanguage</span>) </span>{
  PersonConstructor.call(<span class="hljs-built_in">this</span>, name, age);
  <span class="hljs-built_in">this</span>.programmingLanguage = programmingLanguage;
  <span class="hljs-built_in">this</span>.code = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> is coding in <span class="hljs-subst">${<span class="hljs-built_in">this</span>.programmingLanguage}</span>`</span>);
  };
}

<span class="hljs-comment">// ---  Set up the Prototype Chain for Inheritance! ---</span>
DeveloperPersonConstructor.prototype = <span class="hljs-built_in">Object</span>.create(
  PersonConstructor.prototype
);
</code></pre>
<p>That line <code>DeveloperPersonConstructor.prototype = Object.create(PersonConstructor.prototype);</code> is doing the magic. It's saying, "Hey JavaScript, set the prototype of <code>DeveloperPersonConstructor</code> to be a new object that inherits from <code>PersonConstructor.prototype</code>."</p>
<p>Now, let's try <code>devPerson1.greet()</code> again:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> devPerson1 = <span class="hljs-keyword">new</span> DeveloperPersonConstructor(<span class="hljs-string">"Eve"</span>, <span class="hljs-number">30</span>, <span class="hljs-string">"JavaScript"</span>);

devPerson1.greet(); <span class="hljs-comment">// Output: Hello, I'm Eve  - 🎉 It works now!</span>
</code></pre>
<p><code>devPerson1.greet()</code> now works. <code>devPerson1</code> is inheriting the <code>greet()</code> method from <code>PersonConstructor.prototype</code> through the prototype chain we just set up.</p>
<h3 id="heading-lets-trace-the-prototype-chain">Let's Trace the Prototype Chain</h3>
<p>Let's really understand what's happening when we do <code>devPerson1.greet()</code>:</p>
<ol>
<li><p>JavaScript checks: Does <code>devPerson1</code> itself have a <code>greet</code> property? No.</p>
</li>
<li><p>JavaScript looks at <code>devPerson1</code>'s prototype: <code>DeveloperPersonConstructor.prototype</code>. Does it have a <code>greet</code>property? No, we only added developer-specific methods or properties to <code>DeveloperPersonConstructor</code> directly, not to its prototype in our example. (We could add developer-specific prototype methods later).</p>
</li>
<li><p>JavaScript goes up the prototype chain to <code>DeveloperPersonConstructor.prototype</code>'s prototype: <code>PersonConstructor.prototype</code>. Does it have a <code>greet</code> property? Yes. We defined <code>PersonConstructor.prototype.greet = function() { ... };</code></p>
</li>
<li><p>JavaScript finds <code>greet()</code> on <code>PersonConstructor.prototype</code>, and executes it in the context of <code>devPerson1</code> (so <code>this.name</code> inside <code>greet()</code> refers to <code>devPerson1.name</code>).</p>
</li>
</ol>
<p>Prototype chain in action. <code>devPerson1</code> -&gt; <code>DeveloperPersonConstructor.prototype</code> -&gt; <code>PersonConstructor.prototype</code>-&gt; <code>Object.prototype</code>.</p>
<h3 id="heading-going-even-further-javascript-developer-person">Going Even Further: JavaScript Developer Person</h3>
<p>We can even create longer inheritance chains. Let's say we want to create a <code>JavaScriptDeveloperPersonConstructor</code> that's a special type of <code>DeveloperPersonConstructor</code>, maybe with a specific JavaScript framework preference.</p>
<p>We can do the same pattern:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">JavaScriptDeveloperPersonConstructor</span>(<span class="hljs-params">name, age, framework</span>) </span>{
  <span class="hljs-comment">//  "Borrow" from DeveloperPersonConstructor first!</span>
  DeveloperPersonConstructor.call(<span class="hljs-built_in">this</span>, name, age, <span class="hljs-string">"JavaScript"</span>); <span class="hljs-comment">// Hardcoded "JavaScript"</span>
  <span class="hljs-built_in">this</span>.framework = framework;
  <span class="hljs-built_in">this</span>.codeJavaScript = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// Specific to JavaScript developers</span>
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> is coding in JavaScript with <span class="hljs-subst">${<span class="hljs-built_in">this</span>.framework}</span>`</span>);
  };
}

<span class="hljs-comment">// Set up prototype chain: JavaScriptDeveloperPerson -&gt; DeveloperPerson -&gt; Person</span>
JavaScriptDeveloperPersonConstructor.prototype = <span class="hljs-built_in">Object</span>.create(
  DeveloperPersonConstructor.prototype
);
</code></pre>
<p>Now we have a three-level inheritance chain.</p>
<h3 id="heading-constructor-functions-powerful-but-a-bit-verbose">Constructor Functions: Powerful, but a Bit... Verbose?</h3>
<p>Constructor functions and prototypes are really powerful. They are the fundamental way JavaScript achieves OOP-like behavior. However, as you can see, setting up inheritance with <code>call()</code> and <code>Object.create()</code> can get a bit wordy and tricky to read, especially as inheritance chains get longer.</p>
<p>And guess what? The JavaScript folks noticed this too. In 2015, a new, cleaner syntax for creating object blueprints was introduced in JavaScript.</p>
<h2 id="heading-enter-es6-classes-syntactic-sugar-for-prototypes">Enter ES6 Classes: Syntactic Sugar for Prototypes</h2>
<p>You see, in 2015, JavaScript developers recognized that using prototypes and constructor functions directly to achieve class-like patterns could become verbose and less straightforward to manage as applications grew. Therefore, they introduced the <code>class</code> syntax in ECMAScript 2015 (ES6).</p>
<p>Classes in JavaScript provide a much cleaner and more familiar way to create object blueprints and set up inheritance. But here’s the super important thing to remember: JavaScript classes are still built on top of prototypes. They don't fundamentally change how JavaScript OOP works. They are just syntactic sugar – a nicer, easier way to write code that's still using prototypes behind the scenes.</p>
<p>In the next section, we'll see how to rewrite our <code>Person</code>, <code>DeveloperPerson</code>, and <code>JavaScriptDeveloperPerson</code> examples using the new <code>class</code> syntax, and you'll see how much cleaner and more class-like (pun intended) it feels, while using the power of JavaScript prototypes.</p>
<h2 id="heading-es6-classes-class-syntax-prototypes-in-disguise">ES6 Classes: Class Syntax – Prototypes in Disguise</h2>
<p>Okay, we've wrestled with constructor functions and <code>call()</code> and <code>Object.create()</code> to get inheritance working with prototypes. It's powerful, but let's be honest, it can feel a little verbose and indirect, especially if you're used to class-based languages.</p>
<p>That's where ES6 classes come to the rescue. They offer a much more streamlined and class-like syntax for creating object blueprints in JavaScript.</p>
<p>Let's rewrite our <code>PersonConstructor</code> example using the <code>class</code> syntax. Get ready for a breath of fresh air.</p>
<h3 id="heading-personclass-constructor-function-reimagined-as-a-class"><code>PersonClass</code> - Constructor Function Reimagined as a Class</h3>
<p>Here's how we can define our <code>Person</code> blueprint as a class:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PersonClass</span> </span>{
  <span class="hljs-comment">//  Using the 'class' keyword!</span>
  <span class="hljs-keyword">constructor</span>(name, age) {
    <span class="hljs-comment">//  'constructor' method - like our old constructor function</span>
    <span class="hljs-built_in">this</span>.name = name; <span class="hljs-comment">//  Still using 'this' in the constructor</span>
    <span class="hljs-built_in">this</span>.age = age;
  }

  greet() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Hello, I'm <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>);
  }
}
</code></pre>
<p>Doesn't that look much cleaner and more organized? Let's break down the class syntax:</p>
<ul>
<li><p><code>class PersonClass { ... }</code>: We start with the <code>class</code> keyword, followed by the class name (<code>PersonClass</code> in this case). Class names are conventionally capitalized.</p>
</li>
<li><p><code>constructor(name, age) { ... }</code>: Inside the class, we have a special method called <code>constructor</code>. This is like our old <code>PersonConstructor</code> function. It's where we put the code to initialize the properties of a new <code>PersonClass</code> object when it's created with <code>new</code>. We still use <code>this</code> inside the <code>constructor</code> to refer to the new object being created.</p>
</li>
<li><p><code>greet() { ... }</code>: This is how we define methods in a class. We simply write the method name (<code>greet</code>), followed by parentheses for parameters (none in this case), and then the method body in curly braces. Notice that we don't use the <code>function</code> keyword here. It's just <code>greet() { ... }</code>.</p>
</li>
</ul>
<h3 id="heading-creating-objects-from-a-class-still-using-new">Creating Objects from a Class - Still Using <code>new</code></h3>
<p>To create objects from our <code>PersonClass</code> blueprint, we still use the <code>new</code> keyword, just like we did with constructor functions:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> classPerson1 = <span class="hljs-keyword">new</span> PersonClass(<span class="hljs-string">"Charlie"</span>, <span class="hljs-number">28</span>);
<span class="hljs-keyword">const</span> classPerson2 = <span class="hljs-keyword">new</span> PersonClass(<span class="hljs-string">"Diana"</span>, <span class="hljs-number">32</span>);

<span class="hljs-built_in">console</span>.log(classPerson1.name); <span class="hljs-comment">// Output: Charlie</span>
classPerson1.greet(); <span class="hljs-comment">// Output: Hello, I'm Charlie</span>
</code></pre>
<p>Yep, it works exactly the same way as our constructor function example, but the class syntax is just much more readable and less cluttered.</p>
<h3 id="heading-developerpersonclass-inheritance-made-easy-with-extends"><code>DeveloperPersonClass</code> - Inheritance Made Easy with <code>extends</code></h3>
<p>Now, let's tackle inheritance using classes. Remember how we had to use <code>call()</code> and <code>Object.create()</code> to get <code>DeveloperPersonConstructor</code> to inherit from <code>PersonConstructor</code>? With classes, inheritance becomes super straightforward using the <code>extends</code> keyword.</p>
<p>Here's how we can rewrite <code>DeveloperPersonConstructor</code> as a <code>DeveloperPersonClass</code> that inherits from <code>PersonClass</code>:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DeveloperPersonClass</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">PersonClass</span> </span>{
  <span class="hljs-comment">//  'extends' for inheritance!</span>
  <span class="hljs-keyword">constructor</span>(name, age, programmingLanguage) {
    <span class="hljs-built_in">super</span>(name, age); <span class="hljs-comment">//  'super()' calls the parent class constructor!</span>
    <span class="hljs-built_in">this</span>.programmingLanguage = programmingLanguage;
  }

  code() {
    <span class="hljs-comment">// Developer-specific method</span>
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> is coding in <span class="hljs-subst">${<span class="hljs-built_in">this</span>.programmingLanguage}</span>`</span>);
  }
}
</code></pre>
<p>Look at that. Inheritance in classes is declared using the <code>extends</code> keyword: <code>class DeveloperPersonClass extends PersonClass {...}</code>. This line alone says, "Hey JavaScript, <code>DeveloperPersonClass</code> should inherit from <code>PersonClass</code>."</p>
<p>Inside the <code>DeveloperPersonClass</code> constructor, we have this line: <code>super(name, age);</code>. <code>super()</code> is crucial for class inheritance. It's how we call the constructor of the parent class (<code>PersonClass</code> in this case). When we call <code>super(name, age)</code>, it's essentially doing the same thing as <code>PersonConstructor.call(this, name, age)</code> in our constructor function example—it's running the <code>PersonClass</code> constructor to set up the inherited properties (<code>name</code> and <code>age</code>) on the <code>DeveloperPersonClass</code> object.</p>
<p>After calling <code>super()</code>, we can then add any developer-specific properties or methods to our <code>DeveloperPersonClass</code>, like <code>this.programmingLanguage = programmingLanguage;</code> and the <code>code()</code> method.</p>
<h3 id="heading-using-developerpersonclass-inheritance-in-action-cleaner-syntax">Using <code>DeveloperPersonClass</code> - Inheritance in Action, Cleaner Syntax</h3>
<p>Let's create a <code>DeveloperPersonClass</code> object and see inheritance in action with this cleaner syntax:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> classDevPerson1 = <span class="hljs-keyword">new</span> DeveloperPersonClass(<span class="hljs-string">"Eve"</span>, <span class="hljs-number">35</span>, <span class="hljs-string">"JavaScript"</span>);

<span class="hljs-built_in">console</span>.log(classDevPerson1.name); <span class="hljs-comment">// Output: Eve (Inherited from PersonClass!)</span>
<span class="hljs-built_in">console</span>.log(classDevPerson1.age); <span class="hljs-comment">// Output: 35 (Inherited from PersonClass!)</span>
classDevPerson1.greet(); <span class="hljs-comment">// Output: Hello, I'm Eve (Inherited from PersonClass!)</span>
<span class="hljs-built_in">console</span>.log(classDevPerson1.programmingLanguage); <span class="hljs-comment">// Output: JavaScript (Developer-specific)</span>
classDevPerson1.code(); <span class="hljs-comment">// Output: Eve is coding in JavaScript (Developer-specific)</span>
</code></pre>
<p>It works exactly as expected. <code>classDevPerson1</code> inherits <code>name</code>, <code>age</code>, and <code>greet()</code> from <code>PersonClass</code> and also has its own <code>programmingLanguage</code> and <code>code()</code> methods. But the class syntax makes the inheritance relationship much more obvious and easier to work with.</p>
<h3 id="heading-classes-syntactic-sugar-prototype-power-underneath">Classes: Syntactic Sugar, Prototype Power Underneath</h3>
<p>Let's be crystal clear again: JavaScript classes are syntactic sugar over prototypes. They are a more user-friendly way to write code that is still based on prototypes and constructor functions behind the scenes.</p>
<p>When you define a class, JavaScript is actually doing these things for you under the hood:</p>
<ul>
<li><p>It's creating a constructor function (like our <code>PersonConstructor</code>).</p>
</li>
<li><p>It's setting up the <code>.prototype</code> property of that constructor function.</p>
</li>
<li><p>When you use <code>extends</code>, it's using <code>Object.create()</code> and <code>call() to</code> set up the prototype chain for inheritance.</p>
</li>
</ul>
<p>Classes don't change the fundamental prototype-based nature of JavaScript OOP. They just give us a more familiar and less verbose syntax to work with it.</p>
<h3 id="heading-so-are-classes-just-fake-classes">So, Are Classes Just "Fake" Classes?</h3>
<p>Some people argue that JavaScript classes are “fake” because they’re merely syntactic sugar. But honestly, that’s not the point at all. Syntactic sugar is awesome—it makes our code easier to read, write, and maintain. For those coming from a class-based language background, classes make object-oriented programming in JavaScript much more approachable and understandable.</p>
<p>The key takeaway is that while classes give you a neat, familiar syntax, you still need to understand the underlying mechanism: prototypes. Classes are just a friendly layer on top of JavaScript’s prototype system.</p>
<h2 id="heading-whats-next-more-class-features-and-real-world-examples">What’s Next? More Class Features and Real-World Examples</h2>
<p>Alright, now that you’re comfortable with the idea of classes, it’s time to see them in action. Understanding the theory is only half the battle—we need some practical examples.</p>
<p>And to solidify your understanding, let’s walk through building a classic example: a basic to-do list app. While a to-do app is still relatively simple in concept, it introduces enough front-end interaction to see how classes can organize front-end JavaScript code for interactive elements in a manageable way for learning.</p>
<p>Imagine you want to build a really basic to-do app. What do you need to manage?</p>
<ul>
<li><p>To-dos: Each to-do item has a description and a status (done or not).</p>
</li>
<li><p>Actions: You’ll want to add new to-dos, mark them as complete, delete them, and list them.</p>
</li>
</ul>
<p>This naturally leads us to think of a “ToDo” item as an object, and if you’re creating many to-do items, a <code>ToDo</code> class is a perfect blueprint.</p>
<h3 id="heading-setting-up-your-files">Setting Up Your Files</h3>
<p>Before writing any code, create two files in the same folder:</p>
<ul>
<li><p><code>index.html</code>: This is the webpage structure.</p>
</li>
<li><p><code>script.js</code>: This is where your JavaScript code with classes will live.</p>
</li>
</ul>
<p>You can use any text editor (like VS Code, Sublime Text, or even Notepad) to create these files.</p>
<h3 id="heading-creating-the-todo-class">Creating the ToDo Class</h3>
<p>Let’s start by building our <code>ToDo</code> class. Copy and paste the following code into your <code>script.js</code> file:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ToDo</span> </span>{

<span class="hljs-keyword">constructor</span>(description) {

<span class="hljs-built_in">this</span>.description = description; <span class="hljs-comment">// Every to-do needs a description</span>

<span class="hljs-built_in">this</span>.completed = <span class="hljs-literal">false</span>; <span class="hljs-comment">// By default, it's not completed</span>

}

markComplete() {

<span class="hljs-built_in">this</span>.completed = <span class="hljs-literal">true</span>;

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"${this.description}"</span> marked <span class="hljs-keyword">as</span> complete!);

}

<span class="hljs-comment">// More methods (e.g., for editing the to-do) can be added later.</span>

}
</code></pre>
<p>Notice how clean that is. The <code>constructor</code> sets up the description and completed status for each new to-do item. The <code>markComplete()</code> method updates the status and logs a confirmation message.</p>
<h3 id="heading-building-the-todolist-class">Building the ToDoList Class</h3>
<p>Next, we’ll build a <code>ToDoList</code> class to manage our collection of to-dos. Add the following code to your <code>script.js</code> file, below the <code>ToDo</code> class:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ToDoList</span> </span>{

<span class="hljs-keyword">constructor</span>() {

<span class="hljs-built_in">this</span>.todos = []; <span class="hljs-comment">// Start with an empty array of to-dos</span>

}

addTodo(description) {

<span class="hljs-keyword">const</span> newTodo = <span class="hljs-keyword">new</span> ToDo(description); <span class="hljs-comment">// Create a new ToDo object</span>

<span class="hljs-built_in">this</span>.todos.push(newTodo); <span class="hljs-comment">// Add it to our list</span>

<span class="hljs-built_in">this</span>.renderTodoList(); <span class="hljs-comment">// Update the webpage display</span>

}

listTodos() {

<span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.todos; <span class="hljs-comment">// Return the array of todos (for further processing or rendering)</span>

}

markTodoComplete(index) {

<span class="hljs-keyword">if</span> (index &gt;= <span class="hljs-number">0</span> &amp;&amp; index &lt; <span class="hljs-built_in">this</span>.todos.length) {

<span class="hljs-built_in">this</span>.todos[index].markComplete();

<span class="hljs-built_in">this</span>.renderTodoList(); <span class="hljs-comment">// Update the display after marking complete</span>

}

}

renderTodoList() {

<span class="hljs-keyword">const</span> todoListElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'todoList'</span>);

todoListElement.innerHTML = <span class="hljs-string">''</span>; <span class="hljs-comment">// Clear the current list in HTML</span>

<span class="hljs-built_in">this</span>.todos.forEach(<span class="hljs-function">(<span class="hljs-params">todo, index</span>) =&gt;</span> {

<span class="hljs-keyword">const</span> listItem = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'li'</span>);

listItem.textContent = todo.description;

<span class="hljs-keyword">if</span> (todo.completed) {

listItem.classList.add(<span class="hljs-string">'completed'</span>); <span class="hljs-comment">// Add CSS class for styling completed items</span>

}

<span class="hljs-comment">// Create a "Complete" button for each to-do</span>

<span class="hljs-keyword">const</span> completeButton = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'button'</span>);

completeButton.textContent = <span class="hljs-string">'Complete'</span>;

completeButton.onclick = <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">this</span>.markTodoComplete(index);

listItem.appendChild(completeButton);

todoListElement.appendChild(listItem);

});

}

}
</code></pre>
<p>In this class:</p>
<ul>
<li><p>The <code>constructor</code> initializes an empty array to hold our to-do items.</p>
</li>
<li><p><code>addTodo(description)</code> creates a new <code>ToDo</code> object and adds it to the array, then calls <code>renderTodoList()</code> to update the display.</p>
</li>
<li><p><code>listTodos()</code> returns the list of to-dos.</p>
</li>
<li><p><code>markTodoComplete(index)</code> marks a specific to-do as complete and refreshes the display.</p>
</li>
<li><p><code>renderTodoList()</code> finds the HTML element with the ID <code>todoList</code>, clears its content, and then creates list items for each to-do, including a “Complete” button.</p>
</li>
</ul>
<h3 id="heading-creating-the-html-structure">Creating the HTML Structure</h3>
<p>Next, open your <code>index.html</code> file and paste in the following HTML code:</p>
<pre><code class="lang-javascript">&lt;!DOCTYPE html&gt;

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>My Simple To-Do App<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">

    <span class="hljs-comment">/* Simple CSS to style completed items */</span>

    <span class="hljs-selector-class">.completed</span> {

      <span class="hljs-attribute">text-decoration</span>: line-through;

      <span class="hljs-attribute">color</span>: gray;

    }

  </span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>My To-Do List<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"todoInput"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Enter new to-do..."</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"addButton"</span>&gt;</span>Add To-Do<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"todoList"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"script.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span></span>
</code></pre>
<p>This HTML file sets up:</p>
<ul>
<li><p>A heading for your to-do list.</p>
</li>
<li><p>An input box (with <code>id="todoInput"</code>) for entering new to-dos.</p>
</li>
<li><p>An “Add To-Do” button (with <code>id="addButton"</code>).</p>
</li>
<li><p>An empty unordered list (with <code>id="todoList"</code>) where your to-dos will appear.</p>
</li>
<li><p>A link to the <code>script.js</code> file that contains your JavaScript code.</p>
</li>
</ul>
<h3 id="heading-making-it-all-work-together">Making It All Work Together</h3>
<p>Finally, let’s hook up our HTML elements with our JavaScript. At the bottom of your <code>script.js</code> file, add this code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> myTodoList = <span class="hljs-keyword">new</span> ToDoList(); <span class="hljs-comment">// Create an instance of ToDoList</span>

<span class="hljs-comment">// Get references to the HTML elements</span>

<span class="hljs-keyword">const</span> addButton = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"addButton"</span>);

<span class="hljs-keyword">const</span> todoInput = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"todoInput"</span>);

<span class="hljs-comment">// Listen for clicks on the "Add To-Do" button</span>

addButton.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> todoText = todoInput.value.trim(); <span class="hljs-comment">// Get the text from the input box</span>

  <span class="hljs-keyword">if</span> (todoText) {
    <span class="hljs-comment">// Only add if the input is not empty</span>

    myTodoList.addTodo(todoText); <span class="hljs-comment">// Add the new to-do</span>

    todoInput.value = <span class="hljs-string">""</span>; <span class="hljs-comment">// Clear the input box</span>
  }
});

<span class="hljs-comment">// Render the to-do list initially (it will be empty to start)</span>

myTodoList.renderTodoList();
</code></pre>
<p>This code does the following:</p>
<ul>
<li><p>Creates an instance of the <code>ToDoList</code> class.</p>
</li>
<li><p>Finds the HTML elements for the input and button.</p>
</li>
<li><p>This code adds an event listener to the HTML button element that has the ID "addButton". This listener is set to react to "click" events on this button. When the "Add To-Do" button is clicked, the code inside the event listener function will execute. This code takes the text that the user has typed into the HTML input field with the ID "todoInput" and adds it as a new to-do item to our list.</p>
</li>
<li><p>Initially renders the to-do list on the webpage.</p>
</li>
</ul>
<div class="embed-wrapper">
        <iframe width="100%" height="350" src="https://codepen.io/Spruce_khalifa/embed/vEYBdQe" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="CodePen embed" scrolling="no" allowtransparency="true" allowfullscreen="true" loading="lazy"></iframe></div>
<p> </p>
<h3 id="heading-your-challenge-go-proto-style">Your Challenge: Go Proto-Style</h3>
<p>Now that you’ve seen how classes can make building this to-do app more structured, here’s a challenge: Try building the same to-do app without using the <code>class</code> keyword. Use object literals and prototypes instead. Think about:</p>
<ul>
<li><p>How would you create a <code>ToDo</code> “blueprint” using a constructor function and prototypes?</p>
</li>
<li><p>How would you add the <code>markComplete()</code> method to the <code>ToDo</code> prototype?</p>
</li>
<li><p>How would you structure a <code>ToDoList</code> “blueprint” similarly?</p>
</li>
</ul>
<p>By building the same app using both approaches, you’ll really understand that classes are just a nicer, more familiar way of writing prototype-based code.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Congratulations! You’ve built a basic, interactive to-do app using JavaScript classes and HTML. You now see how classes help you organize code and encapsulate related functionality. While classes are just syntactic sugar over prototypes, they make it much easier to write, read, and maintain your code—especially as your applications grow.</p>
<p>Your next step? Experiment with the prototype approach and compare it with the class-based approach. The more you code, the more natural these concepts will become. Happy coding, and keep building cool stuff.</p>
<p>If you have any questions, feel free to find me on Twitter at <a target="_blank" href="https://x.com/sprucekhalifa">@sprucekhalifa</a>, and don’t forget to follow me for more tips and updates. Happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <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>
        
            <item>
                <title>
                    <![CDATA[ Master Object Oriented Programming in Python ]]>
                </title>
                <description>
                    <![CDATA[ Object-oriented programming (OOP) is one of the most essential paradigms in modern software development. It provides a structured way to design and organize code, making it more reusable, maintainable, and scalable. Unlike procedural programming, whi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/master-object-oriented-programming-in-python/</link>
                <guid isPermaLink="false">679a52c025db32662cde422f</guid>
                
                    <category>
                        <![CDATA[ Object Oriented Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Wed, 29 Jan 2025 16:09:36 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1738189114736/ff24cbf4-c956-4944-8021-a682d31abc03.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Object-oriented programming (OOP) is one of the most essential paradigms in modern software development. It provides a structured way to design and organize code, making it more reusable, maintainable, and scalable. Unlike procedural programming, which follows a linear approach, OOP focuses on creating objects—self-contained units that bundle data and functionality together. This approach not only mirrors real-world entities but also makes complex applications easier to manage and expand.</p>
<p>We just published a course on the freeCodeCamp.org YouTube channel that provides a comprehensive introduction to object-oriented programming using Python. Created by Dan Adams, this beginner-friendly course covers the fundamental concepts of OOP, including classes and objects, attributes and methods, inheritance, encapsulation, abstraction, and polymorphism. Through clear explanations and practical examples, this course will help you develop the skills needed to write clean, maintainable, and scalable code using Python.</p>
<h3 id="heading-what-you-will-learn">What You Will Learn</h3>
<p>This course is designed to take learners from the basics of OOP to more advanced concepts, ensuring a deep understanding of how object-oriented programming works in Python. Below is an overview of the key topics covered.</p>
<h4 id="heading-understanding-classes-and-objects">Understanding Classes and Objects</h4>
<p>The foundation of OOP lies in understanding classes and objects. A <strong>class</strong> serves as a blueprint for creating objects, while an <strong>object</strong> is an instance of a class with its own unique data and behavior. This section explains how to define classes, create objects, and work with attributes and methods to encapsulate functionality within objects.</p>
<h4 id="heading-attributes-methods-and-access-modifiers">Attributes, Methods, and Access Modifiers</h4>
<p>Objects contain <strong>attributes</strong>, which store data, and <strong>methods</strong>, which define the behavior of an object. Python provides mechanisms to control access to these attributes and methods using <strong>access modifiers</strong>, such as public, protected, and private attributes. This section covers how to use and modify object attributes, when to make attributes private or protected, and Python’s philosophy on data protection.</p>
<h4 id="heading-getters-setters-and-properties">Getters, Setters, and Properties</h4>
<p>Encapsulation is a key principle of OOP that involves restricting direct access to an object's internal data. This is achieved through <strong>getter and setter methods</strong>, which control how data is accessed and modified. The course also introduces <strong>Python properties</strong>, a more Pythonic way to manage attribute access without explicitly defining getter and setter methods.</p>
<h4 id="heading-static-attributes-and-methods">Static Attributes and Methods</h4>
<p>Not all attributes and methods belong to individual instances of a class. <strong>Static attributes</strong> are shared across all instances of a class, while <strong>static methods</strong> operate independently of any specific object. This section explains when and why to use static attributes and methods to improve code efficiency and organization.</p>
<h4 id="heading-encapsulation-and-abstraction">Encapsulation and Abstraction</h4>
<p>Encapsulation helps to bundle data and functionality together while restricting direct access to certain components, making the code more secure and maintainable. <strong>Abstraction</strong>, on the other hand, focuses on hiding unnecessary details and exposing only what is essential. This section discusses the importance of both concepts and how they contribute to writing clean and efficient software.</p>
<h4 id="heading-inheritance-reusing-and-extending-code">Inheritance: Reusing and Extending Code</h4>
<p><strong>Inheritance</strong> is one of the most powerful features of OOP, allowing developers to create new classes that inherit functionality from existing ones. This promotes code reuse and reduces duplication. The course demonstrates how to implement inheritance in Python, create base and derived classes, and override methods to extend or modify existing functionality.</p>
<h4 id="heading-polymorphism-writing-flexible-and-scalable-code">Polymorphism: Writing Flexible and Scalable Code</h4>
<p><strong>Polymorphism</strong> allows objects of different classes to be treated as if they belong to the same class, enabling greater flexibility in software design. The course introduces the concept of polymorphism and demonstrates how it can be used to write more adaptable and scalable code.</p>
<h3 id="heading-why-learn-object-oriented-programming">Why Learn Object-Oriented Programming?</h3>
<p>Object-oriented programming is widely used in the software industry and is a fundamental skill for developers working on large-scale applications. Understanding OOP provides several benefits:</p>
<ul>
<li><p><strong>Improved Code Organization</strong> – OOP structures code into modular, reusable components, making it easier to read and manage.</p>
</li>
<li><p><strong>Enhanced Code Maintainability</strong> – Encapsulation and abstraction help prevent unintended modifications, reducing the risk of errors.</p>
</li>
<li><p><strong>Code Reusability</strong> – Inheritance allows developers to reuse existing functionality instead of rewriting code from scratch.</p>
</li>
<li><p><strong>Scalability</strong> – OOP principles enable applications to grow in complexity without becoming unmanageable.</p>
</li>
<li><p><strong>Industry Relevance</strong> – Many programming languages and frameworks are based on OOP, making it a valuable skill for any developer.</p>
</li>
</ul>
<h3 id="heading-course-structure">Course Structure</h3>
<p>The course is structured to gradually introduce concepts, ensuring that learners fully grasp each topic before moving on. Below is a general outline of the course contents:</p>
<ul>
<li><p><strong>Introduction</strong> – Overview of object-oriented programming and its importance.</p>
</li>
<li><p><strong>Creating Classes and Objects</strong> – Understanding how to define and instantiate objects in Python.</p>
</li>
<li><p><strong>Working with Object Attributes and Methods</strong> – Learning how to modify and access data within objects.</p>
</li>
<li><p><strong>Encapsulation and Data Protection</strong> – Implementing public, protected, and private attributes.</p>
</li>
<li><p><strong>Inheritance and Code Reusability</strong> – Using inheritance to build more efficient programs.</p>
</li>
<li><p><strong>Polymorphism and Flexibility</strong> – Applying polymorphism to create adaptable code.</p>
</li>
<li><p><strong>Conclusion</strong> – Summarizing key concepts and reinforcing best practices.</p>
</li>
</ul>
<h3 id="heading-start-learning-today">Start Learning Today</h3>
<p>By the end of this course, learners will have a strong understanding of object-oriented programming and the ability to confidently apply OOP principles to real-world projects. Watch the full course on <a target="_blank" href="https://youtu.be/iLRZi0Gu8Go">the freeCodeCamp.org YouTube channel</a> (3-hour watch).</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/iLRZi0Gu8Go" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Object-Oriented Programming in Python – Key OOP Concepts and Interview Questions for Beginners ]]>
                </title>
                <description>
                    <![CDATA[ OOP is a crucial concept that every developer should grasp, especially when getting ready for job interviews. It helps you organize code into modular and reusable sections, which simplifies the development, maintenance, and scaling of software applic... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/object-oriented-programming-in-python-interview-questions/</link>
                <guid isPermaLink="false">671aeea7c5f85f75b4b243e8</guid>
                
                    <category>
                        <![CDATA[ Object Oriented Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ interview questions ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Casmir Onyekani ]]>
                </dc:creator>
                <pubDate>Fri, 25 Oct 2024 01:04:39 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1729679277832/18ab2f5b-0636-44e7-b063-0773e5039fb0.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>OOP is a crucial concept that every developer should grasp, especially when getting ready for job interviews. It helps you organize code into modular and reusable sections, which simplifies the development, maintenance, and scaling of software applications.</p>
<p>In this article, I'll use some common interview questions to simplify the key OOP concepts, providing clear explanations and code snippets to boost your confidence for your next interview.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-is-oop">What is OOP?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-are-the-four-main-principles-of-oop">What are the Four Main Principles of OOP</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-method-overloading">What is Method Overloading?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-a-constructor-in-oop">What is a Constructor in OOP?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-a-destructor-in-oop">What is a Destructor in OOP?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-a-class-in-oop">What is a Class in OOP?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-an-object-in-oop">What is an Object in OOP?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-a-static-method">What is a Static Method?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-the-difference-between-a-class-variable-and-an-instance-variable">What is the Difference Between a Class Variable and an Instance Variable?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-does-python-support-multiple-inheritance">Does Python Support Multiple Inheritance?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-the-difference-between-an-abstract-class-and-an-interface">What is the Difference Between an Abstract Class and an Interface?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-what-is-oop">What is OOP?</h2>
<p>Object-Oriented Programming (OOP) is a way of writing software that revolves around objects<strong>.</strong> These objects can store data and their actions (methods). Rather than concentrating solely on processes and logic, OOP encourages you to structure your code around these objects.</p>
<p>This approach makes it easier to create modular, reusable, and scalable software designs.</p>
<h2 id="heading-what-are-the-four-main-principles-of-oop">What are the Four Main Principles of OOP</h2>
<p>The four pillars of OOP are:</p>
<ul>
<li><p>Encapsulation</p>
</li>
<li><p>Abstraction</p>
</li>
<li><p>Inheritance</p>
</li>
<li><p>Polymorphism</p>
</li>
</ul>
<h3 id="heading-what-is-encapsulation-and-why-is-it-important">What is Encapsulation, and Why is it Important?</h3>
<p>Encapsulation helps protect the data inside an object. Think of it like keeping certain details private, allowing only controlled access to them.</p>
<p>That is, instead of directly changing or viewing the data, you interact with it through specific methods. This ensures that the data is safe from unintended changes.</p>
<p>Example:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Person</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, name, age</span>):</span>
        self.name = name
        self.__age = age  <span class="hljs-comment"># Private attribute (notice the double underscore)</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_age</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> self.__age  <span class="hljs-comment"># A method to access the private age attribute</span>
</code></pre>
<p>In this example, <code>__age</code> is kept private, and we can only get the age using the <code>get_age()</code> method. This ensures that <code>age</code> is not accidentally modified in a way that could cause issues.</p>
<h3 id="heading-what-is-abstraction-and-how-is-it-different-from-encapsulation">What is Abstraction, and How is it Different from Encapsulation?</h3>
<p>Abstraction allows you to show only the important details of an object or system, while hiding the complex parts that the user doesn't need to see.</p>
<p>Think of it like driving a car, you only need to know how to use the steering wheel, gear, gas pedal, and brakes to drive. You don’t need to understand how the engine works internally.</p>
<p>In programming, abstraction helps you focus on what something does, not how it works inside.</p>
<p><strong>Example:</strong> Let’s say you’re using a <code>Car</code> class. The abstraction lets you start the car without knowing all the mechanical details:</p>
<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">start_engine</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">"Engine started"</span>)

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

<span class="hljs-comment"># The user interacts with the car without knowing how the engine works</span>
my_car = Car()
my_car.start_engine()
my_car.drive()
</code></pre>
<p>Here, you don’t need to worry about how the <code>start_engine</code> method works internally, you just use it!</p>
<p>Key Difference:</p>
<ul>
<li><p>Encapsulation: Focuses on bundling data and restricting access.</p>
</li>
<li><p>Abstraction: Focuses on hiding complexity and exposing only necessary details.</p>
</li>
</ul>
<h3 id="heading-what-is-inheritance-in-oop">What is inheritance in OOP?</h3>
<p>Inheritance lets you create a new class by using an existing class. The new class (called the child class) gets all the attributes and methods from the existing class (called the parent class).</p>
<p>This allows you to reuse code and build upon what you've already written without starting from scratch.</p>
<p>Example:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Parent class</span>
<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</span>):</span>
        self.brand = brand  <span class="hljs-comment"># This is an attribute (brand)</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">f"<span class="hljs-subst">{self.brand}</span> vehicle started"</span>)  <span class="hljs-comment"># This is a method</span>

<span class="hljs-comment"># Child class that inherits from Vehicle</span>
<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</span>):</span>
        super().__init__(brand)  <span class="hljs-comment"># Inherit the brand from Vehicle (parent class)</span>
        self.model = model  <span class="hljs-comment"># Add a new attribute specific to Car</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">display_info</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">f"Car: <span class="hljs-subst">{self.brand}</span>, Model: <span class="hljs-subst">{self.model}</span>"</span>)

<span class="hljs-comment"># Creating an object of the Car class</span>
my_car = Car(<span class="hljs-string">"IVM"</span>, <span class="hljs-string">"Ikenga"</span>)
my_car.start()  <span class="hljs-comment"># Output: IVM vehicle started</span>
my_car.display_info()  <span class="hljs-comment"># Output: Car: IVM, Model: Ikenga</span>
</code></pre>
<p>In this example, <code>Vehicle</code> is the parent class, and <code>Car</code> is the child class. <code>Car</code> inherits the <code>brand</code> and <code>start()</code> method from <code>Vehicle</code>, but it also has its own attribute (<code>model</code>) and method (<code>display_info()</code>).</p>
<p>Inheritance makes it easier to create more specialized classes (like <code>Car</code>) based on a general class (like <code>Vehicle</code>).</p>
<h3 id="heading-what-is-polymorphism">What is Polymorphism?</h3>
<p>Polymorphism allows different types of objects to respond to the same action in their own unique way. It’s like how both cats and dogs make sounds, but each makes a different sound when you ask them to!</p>
<p>Polymorphism can be achieved through method overriding (when a child class has a method with the same name as a method in its parent class but provides its own implementation).</p>
<p>Example of method overriding:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Parent class</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">sound</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> <span class="hljs-string">"Some generic animal sound"</span>

<span class="hljs-comment"># Child class Dog overriding the sound method</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span>(<span class="hljs-params">Animal</span>):</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">sound</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> <span class="hljs-string">"Bark"</span>

<span class="hljs-comment"># Child class Cat overriding the sound method</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Cat</span>(<span class="hljs-params">Animal</span>):</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">sound</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> <span class="hljs-string">"Meow"</span>

<span class="hljs-comment"># Creating instances of each class</span>
my_dog = Dog()
my_cat = Cat()

<span class="hljs-comment"># Calling the sound method</span>
print(my_dog.sound())  <span class="hljs-comment"># Output: Bark</span>
print(my_cat.sound())  <span class="hljs-comment"># Output: Meow</span>
</code></pre>
<p>In this example:</p>
<ul>
<li><p><code>Animal</code> is the parent class, and it has a method called <code>sound()</code>.</p>
</li>
<li><p>Both <code>Dog</code> and <code>Cat</code> are child classes of <code>Animal</code>, and they override the <code>sound()</code> method to provide their own specific sound.</p>
</li>
<li><p>When you call <code>sound()</code> on a dog, it returns "Bark", and for a cat, it returns "Meow."</p>
</li>
</ul>
<p>This is polymorphism in action, different objects (Dog, Cat) responding to the same method (<code>sound()</code>) in different ways.</p>
<p>It's a powerful tool that helps in creating flexible and easy-to-maintain code!</p>
<h2 id="heading-what-is-method-overloading">What is Method Overloading?</h2>
<p>Method overloading happens when you create multiple methods with the same name, but with different types of parameters inside the same class.</p>
<p>While Python doesn't support traditional method overloading, you can mimic similar behavior by using default arguments/parameters or handling multiple arguments inside the method.</p>
<p>Example 1: Using Default Parameters</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Calculator</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add</span>(<span class="hljs-params">self, a, b=<span class="hljs-number">0</span>, c=<span class="hljs-number">0</span></span>):</span>
        <span class="hljs-keyword">return</span> a + b + c

<span class="hljs-comment"># Create an instance of Calculator</span>
calc = Calculator()

<span class="hljs-comment"># Call the add method with different numbers of arguments</span>
print(calc.add(<span class="hljs-number">5</span>))        <span class="hljs-comment"># Output: 5 (a = 5, b and c default to 0)</span>
print(calc.add(<span class="hljs-number">5</span>, <span class="hljs-number">10</span>))    <span class="hljs-comment"># Output: 15 (a = 5, b = 10, c default to 0)</span>
print(calc.add(<span class="hljs-number">5</span>, <span class="hljs-number">10</span>, <span class="hljs-number">15</span>))<span class="hljs-comment"># Output: 30 (a = 5, b = 10, c = 15)</span>
</code></pre>
<p>In this example, the <code>add</code> method has one required parameter (<code>a</code>) and two optional parameters (<code>b</code> and <code>c</code>) with default values of <code>0</code>.</p>
<p>By changing the number of arguments you pass when calling the method, you can achieve a method overloading effect.</p>
<p>Example 2: Using <code>*args</code> for Dynamic Parameters</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Calculator</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add</span>(<span class="hljs-params">self, *args</span>):</span>
        <span class="hljs-keyword">return</span> sum(args)

<span class="hljs-comment"># Create an instance of Calculator</span>
calc = Calculator()

<span class="hljs-comment"># Call the add method with different numbers of arguments</span>
print(calc.add(<span class="hljs-number">5</span>))           <span class="hljs-comment"># Output: 5 (adds just one number)</span>
print(calc.add(<span class="hljs-number">5</span>, <span class="hljs-number">10</span>))       <span class="hljs-comment"># Output: 15 (adds two numbers)</span>
print(calc.add(<span class="hljs-number">5</span>, <span class="hljs-number">10</span>, <span class="hljs-number">15</span>))   <span class="hljs-comment"># Output: 30 (adds three numbers)</span>
</code></pre>
<p>In this example, the <code>add</code> method can handle any number of arguments thanks to <code>*args</code>, allowing you to call the method with one or more parameters. It sums up all the numbers passed to it.</p>
<h2 id="heading-what-is-a-constructor-in-oop">What is a Constructor in OOP?</h2>
<p>A constructor is a special method that automatically runs when you create a new object from a class. It helps to set up the object's initial values (like setting the name or age of a person).</p>
<p>In Python, the constructor method is named <code>__init__</code>, which stands for "initialize”.</p>
<p>Example:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Student</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, name, grade</span>):</span>  <span class="hljs-comment"># The constructor method</span>
        self.name = name  <span class="hljs-comment"># Setting the name when the object is created</span>
        self.grade = grade  <span class="hljs-comment"># Setting the grade when the object is created</span>

<span class="hljs-comment"># Creating a new Student object</span>
student1 = Student(<span class="hljs-string">"Alice"</span>, <span class="hljs-string">"A"</span>)

<span class="hljs-comment"># Accessing the student's details</span>
print(student1.name)  <span class="hljs-comment"># Output: Alice</span>
print(student1.grade)  <span class="hljs-comment"># Output: A</span>
</code></pre>
<p>In this example, the <code>__init__</code> method automatically assigns the values for <code>name</code> and <code>grade</code> when we create a <code>Student</code> object (like <code>student1</code>).When you print <code>student1.name</code>, it shows "Alice," and <code>student1.grade</code> shows "A."</p>
<p>This helps to set up each student object with different details when needed!</p>
<h2 id="heading-what-is-a-destructor-in-oop">What is a Destructor in OOP?</h2>
<p>A destructor is a method that is called when an object is destroyed. In Python, the destructor is defined using <code>__del__</code>.</p>
<p>Example:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Demo</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">"Constructor called"</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__del__</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">"Destructor called"</span>)

obj = Demo()
<span class="hljs-keyword">del</span> obj  <span class="hljs-comment"># Explicitly calling the destructor</span>
</code></pre>
<p>In this example, the <code>Demo</code> class has a constructor (<code>__init__</code>) that prints "Constructor called" when an object is created, and a destructor (<code>__del__</code>) that prints "Destructor called" when the object is deleted.</p>
<p>The <code>del obj</code> explicitly triggers the destructor to clean up the object.</p>
<h2 id="heading-what-is-a-class-in-oop">What is a Class in OOP?</h2>
<p>A class is like a template for making objects in programming. It outlines what properties (called attributes) and actions (called methods) the objects will have. Think of a class as a recipe that tells you how to create something, like a car.</p>
<p>Example:</p>
<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, make, model</span>):</span>
        self.make = make  <span class="hljs-comment"># The brand of the car, like IVM</span>
        self.model = model  <span class="hljs-comment"># The specific model, like Ikenga</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">display_info</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> <span class="hljs-string">f"Car: <span class="hljs-subst">{self.make}</span>, Model: <span class="hljs-subst">{self.model}</span>"</span>  <span class="hljs-comment"># Shows the car's information</span>
</code></pre>
<p>In this example:</p>
<ul>
<li><p><code>Car</code> is the class that describes what a car is.</p>
</li>
<li><p><code>make</code> and <code>model</code> are attributes that hold information about the car.</p>
</li>
<li><p><code>display_info</code> is a method that tells us how to get details about the car.</p>
</li>
</ul>
<p>When we create a car object from this class, it will have its own make and model, just like real cars do!</p>
<h2 id="heading-what-is-an-object-in-oop">What is an Object in OOP?</h2>
<p>An object is a specific example of a class. Think of it like a real-life item that has certain characteristics defined by the class. When you create an object, you're giving it actual values for its properties.</p>
<pre><code class="lang-python">my_car = Car(<span class="hljs-string">"IVM"</span>, <span class="hljs-string">"Ikenga"</span>)
print(my_car.display_info())  <span class="hljs-comment"># This will show: Car: IVM, Model: Ikenga</span>
</code></pre>
<p>In this example, <code>my_car</code> is an object created from the <code>Car</code> class.</p>
<h2 id="heading-what-is-a-static-method">What is a Static Method?</h2>
<p>This is a method that belongs to a class, not to an instance (object) of that class. Unlike other methods, static methods don’t need access to instance-specific data (attributes) or class-specific data.</p>
<p>You can call a static method directly from the class without creating an object.</p>
<p>Example:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MathOperations</span>:</span>
<span class="hljs-meta">    @staticmethod  # This tells Python it's a static method</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add</span>(<span class="hljs-params">a, b</span>):</span>
        <span class="hljs-keyword">return</span> a + b

<span class="hljs-comment"># We don't need to create an object of the class to use the static method</span>
result = MathOperations.add(<span class="hljs-number">5</span>, <span class="hljs-number">3</span>)
print(result)  <span class="hljs-comment"># Output: 8</span>
</code></pre>
<p>In this example, <code>@staticmethod</code> is used to define the method as static. You can call <code>MathOperations.add()</code> directly using the class name, without creating an object of <code>MathOperations</code>.</p>
<h2 id="heading-what-is-the-difference-between-a-class-variable-and-an-instance-variable">What is the Difference Between a Class Variable and an Instance Variable?</h2>
<p>A class variable is shared among all instances of a class, while an instance variable is specific to each object and defined inside methods, usually within the constructor.</p>
<p>Example:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyClass</span>:</span>
    class_var = <span class="hljs-string">"I am a class variable"</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, instance_var</span>):</span>
        self.instance_var = instance_var  <span class="hljs-comment"># Instance variable</span>
</code></pre>
<p>In this example, a class <code>MyClass</code> has a class variable <code>class_var</code> that is shared by all instances, and an instance variable <code>instance_var</code> that is unique to each object created from the class.</p>
<h2 id="heading-does-python-support-multiple-inheritance">Does Python Support Multiple Inheritance?</h2>
<p>Yes, Python allows multiple inheritance, where a class can inherit from more than one parent class.</p>
<p>Example:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Parent1</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">display</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">"Parent1"</span>)

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Parent2</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">display</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">"Parent2"</span>)

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Child</span>(<span class="hljs-params">Parent1, Parent2</span>):</span>
    <span class="hljs-keyword">pass</span>

child = Child()
child.display()  <span class="hljs-comment"># Method resolution order determines which display() is called</span>
</code></pre>
<p>In this example, the <code>Child</code> class inherits from both <code>Parent1</code> and <code>Parent2</code>, and due to the <a target="_blank" href="https://docs.python.org/3/howto/mro.html">method resolution order (MRO)</a>, <code>Child</code> will call <code>Parent1</code>'s <code>display()</code> method first.</p>
<h2 id="heading-what-is-the-difference-between-an-abstract-class-and-an-interface">What is the Difference Between an Abstract Class and an Interface?</h2>
<p>An abstract class is a special type of class that you cannot create an object from. It can have both incomplete methods (called abstract methods) that don’t have any implementation, as well as fully implemented methods that do have code.</p>
<p>An interface is like a contract that defines methods that must be implemented by any class that uses it. In Python, we achieve interfaces through abstract base classes (ABCs), which only contain abstract methods. They don’t have any implementation.</p>
<p>Simple example to illustrate the concepts:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> abc <span class="hljs-keyword">import</span> ABC, abstractmethod

<span class="hljs-comment"># Abstract Class</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span>(<span class="hljs-params">ABC</span>):</span>
<span class="hljs-meta">    @abstractmethod</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">sound</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">pass</span>  <span class="hljs-comment"># This is an abstract method, no implementation</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">sleep</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> <span class="hljs-string">"Sleeping..."</span>  <span class="hljs-comment"># This is a regular method with implementation</span>

<span class="hljs-comment"># Subclass that implements the abstract method</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span>(<span class="hljs-params">Animal</span>):</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">sound</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> <span class="hljs-string">"Bark"</span>  <span class="hljs-comment"># Implementation of the abstract method</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Cat</span>(<span class="hljs-params">Animal</span>):</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">sound</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> <span class="hljs-string">"Meow"</span>  <span class="hljs-comment"># Another implementation of the abstract method</span>

<span class="hljs-comment"># Using the classes</span>
my_dog = Dog()
print(my_dog.sound())  <span class="hljs-comment"># Output: Bark</span>
print(my_dog.sleep())  <span class="hljs-comment"># Output: Sleeping...</span>

my_cat = Cat()
print(my_cat.sound())  <span class="hljs-comment"># Output: Meow</span>
print(my_cat.sleep())  <span class="hljs-comment"># Output: Sleeping...</span>
</code></pre>
<p>In this example, an abstract class <code>Animal</code> with an abstract method <code>sound</code>, and two subclasses, <code>Dog</code> and <code>Cat</code>, implement the <code>sound</code> method, demonstrating the use of abstract classes and method overriding in Python.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Understanding these OOP principles is crucial for any developer. It forms the foundation of most modern programming languages.</p>
<p>By mastering the key concepts and being prepared for interview questions, you’ll not only build better software but also enhance your chances of landing your next developer role.</p>
<p>If you found this guide helpful please give it a like. You can follow me on <a target="_blank" href="https://x.com/casweb_dev">X</a> for more insightful articles.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What are the SOLID Principles in C#? Explained With Code Examples ]]>
                </title>
                <description>
                    <![CDATA[ The SOLID Principles are five software design principles that help you to write high quality, flexible, maintainable, reusable, testable, and readable software. If you plan to work with object-oriented software, it is crucial to understand these five... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-are-the-solid-principles-in-csharp/</link>
                <guid isPermaLink="false">671a62b68210490d9d68e83f</guid>
                
                    <category>
                        <![CDATA[ Object Oriented Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ C# ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ design patterns ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Software Engineering ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software architecture ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Danny ]]>
                </dc:creator>
                <pubDate>Thu, 24 Oct 2024 15:07:34 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1729777076695/7d956373-1835-4823-9a6a-d2d232cd64d5.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The SOLID Principles are five software design principles that help you to write high quality, flexible, maintainable, reusable, testable, and readable software. If you plan to work with object-oriented software, it is crucial to understand these five principles.</p>
<p>The SOLID Principles were introduced by a software engineer named Robert C. Martin (also known as "Uncle Bob") in the early 2000s. Uncle Bob’s goal was to promote good software design practices, particularly in object-oriented programming (OOP), by addressing common problems developers face as software systems grow in size and complexity.</p>
<p>Here are the five SOLID principles:</p>
<ul>
<li><p><strong>S</strong>: <a class="post-section-overview" href="#heading-single-responsibility-principle-srp">Single Responsibility Principle (SRP)</a></p>
</li>
<li><p><strong>O</strong>: <a class="post-section-overview" href="#heading-open-closed-principle-ocp">Open-closed Principle (OCP)</a></p>
</li>
<li><p><strong>L</strong>: <a class="post-section-overview" href="#heading-liskov-substitution-principle-lsp">Liskov Substitution Principle (LSP)</a></p>
</li>
<li><p><strong>I</strong>: <a class="post-section-overview" href="#heading-interface-segregation-principle-isp">Interface Segregation Principle (ISP)</a></p>
</li>
<li><p><strong>D</strong>: <a class="post-section-overview" href="#heading-dependency-inversion-principle-dip">Dependency Inversion Principle (DIP)</a></p>
</li>
</ul>
<p>By following these principles, you can create software designs that are easier to understand, maintain, and extend, leading to higher-quality software that is more robust and adaptable to change.</p>
<p>In this article, to demonstrate each principle, I’ll first show you a bad code example in C# that violates the principle. We will then discuss the issues this bad code causes, and then solve those issues by refactoring the code to satisfy the principle.</p>
<p>First up we have the…</p>
<h2 id="heading-single-responsibility-principle-srp-in-c">Single Responsibility Principle (SRP) in C</h2>
<blockquote>
<p>A class should have only one reason to change, meaning that it should have only one responsibility or purpose.</p>
</blockquote>
<p>This principle encourages you to create classes that are more focussed and perform one single well-defined task, rather than multiple tasks. Breaking up classes into smaller, more focused units makes code easier to understand, maintain, and test.</p>
<p><strong>An example that violates the SRP:</strong></p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">User</span>
{
 <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Username { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
 <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Email { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Register</span>(<span class="hljs-params"></span>)</span>
 {
   <span class="hljs-comment">// Register user logic, e.g. save to database...</span>

   <span class="hljs-comment">// Send email notification</span>
   EmailSender emailSender = <span class="hljs-keyword">new</span> EmailSender();
   emailSender.SendEmail(<span class="hljs-string">"Welcome to our platform!"</span>, Email);
 }
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">EmailSender</span>
{
 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">SendEmail</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> message, <span class="hljs-keyword">string</span> recipient</span>)</span>
 {
   <span class="hljs-comment">// Email sending logic</span>
   Console.WriteLine(<span class="hljs-string">$"Sending email to <span class="hljs-subst">{recipient}</span>: <span class="hljs-subst">{message}</span>"</span>);
 }
}
</code></pre>
<p>In this example, the <code>User</code> class manages user data (username and email), and contains logic for registering a user. This violates the SRP because the class has more than one reason to change. It could change due to:</p>
<ul>
<li><p>Modifications in user data management – for example adding more fields, such as <code>firstName</code>, <code>gender</code>, <code>hobbies</code>.</p>
</li>
<li><p>Modifications to the logic of registering a user, for example we may choose to fetch a user from the database by their username rather than their email.</p>
</li>
</ul>
<p>To adhere to the Single Responsibility Principle, we should separate these responsibilities into separate classes. </p>
<p><strong>Refactoring the code to satisfy the SRP</strong>:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">User</span>
{
 <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Username { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
 <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Email { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">EmailSender</span>
{
 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">SendEmail</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> message, <span class="hljs-keyword">string</span> recipient</span>)</span>
 {
   <span class="hljs-comment">// Email sending logic</span>
   Console.WriteLine(<span class="hljs-string">$"Sending email to <span class="hljs-subst">{recipient}</span>: <span class="hljs-subst">{message}</span>"</span>);
 }
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">UserService</span>
{
 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">RegisterUser</span>(<span class="hljs-params">User user</span>)</span>
 {
   <span class="hljs-comment">// Register user logic...</span>

   EmailSender emailSender = <span class="hljs-keyword">new</span> EmailSender();
   emailSender.SendEmail(<span class="hljs-string">"Welcome to our platform!"</span>, user.Email);
 }
}
</code></pre>
<p>In the refactored code, the <code>User</code> class is responsible solely for representing user data. The <code>UserService</code> class now handles user registration, separating concerns related to user data management from user registration logic. The <code>UserService</code> class is responsible only for the business logic of registering a user.</p>
<p>This separation of responsibilities adheres to the Single Responsibility Principle, making the code easier to understand, maintain, and extend.</p>
<h2 id="heading-openclosed-principle-ocp-in-c">Open/Closed Principle (OCP) in C</h2>
<blockquote>
<p>Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification.</p>
</blockquote>
<p>This principle promotes the idea that existing code should be able to be extended with new functionality without modifying its source code. It encourages the use of abstraction and polymorphism to achieve this goal, allowing for code to be easily extended through inheritance or composition.</p>
<p>(By the way, if you don’t understand these fundamental OOP concepts, such as abstraction, polymorphism, inheritance and composition — then check out my book, <a target="_blank" href="https://www.amazon.com/Mastering-Design-Patterns-Beginner-Friendly-Principles/dp/B0DB6MLYYZ">Mastering Design Patterns in C#: A Beginner-Friendly Guide, Including OOP and SOLID Principles on Amazon</a> or <a target="_blank" href="https://doabledanny.gumroad.com/l/ennyj?layout=profile">Gumroad</a>.)</p>
<p>Let's consider an example of a <code>Shape</code> class hierarchy that calculates the area of different geometric shapes. Initially, this violates the Open/Closed Principle because adding a new shape requires modifying the existing code:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">enum</span> ShapeType
{
 Circle,
 Rectangle
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Shape</span>
{
 <span class="hljs-keyword">public</span> ShapeType Type { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
 <span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> Radius { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
 <span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> Length { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
 <span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> Width { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">CalculateArea</span>(<span class="hljs-params"></span>)</span>
 {
   <span class="hljs-keyword">switch</span> (Type)
   {
     <span class="hljs-keyword">case</span> ShapeType.Circle:
       <span class="hljs-keyword">return</span> Math.PI * Math.Pow(Radius, <span class="hljs-number">2</span>);
     <span class="hljs-keyword">case</span> ShapeType.Rectangle:
       <span class="hljs-keyword">return</span> Length * Width;
     <span class="hljs-keyword">default</span>:
       <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> InvalidOperationException(<span class="hljs-string">"Unsupported shape type."</span>);
   }
 }
}
</code></pre>
<p>In this example, the <code>Shape</code> class has a method, <code>CalculateArea()</code>, that calculates the area based on the type of shape. Adding a new shape, such as a triangle, would require modifying the existing <code>Shape</code> class, violating the OCP.</p>
<p>To adhere to the Open/Closed Principle, we should design the system in a way that allows for extension without modification. Let's refactor the code using inheritance and polymorphism:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Shape</span>
{
 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">double</span> <span class="hljs-title">CalculateArea</span>(<span class="hljs-params"></span>)</span>;
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Circle</span> : <span class="hljs-title">Shape</span>
{
 <span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> Radius { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">double</span> <span class="hljs-title">CalculateArea</span>(<span class="hljs-params"></span>)</span>
 {
   <span class="hljs-keyword">return</span> Math.PI * Math.Pow(Radius, <span class="hljs-number">2</span>);
 }
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Rectangle</span> : <span class="hljs-title">Shape</span>
{
 <span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> Length { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
 <span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> Width { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">double</span> <span class="hljs-title">CalculateArea</span>(<span class="hljs-params"></span>)</span>
 {
   <span class="hljs-keyword">return</span> Length * Width;
 }
}
</code></pre>
<p>In this refactored code, we define an abstract <code>Shape</code> class with an abstract <code>CalculateArea()</code> method. Concrete shape classes (<code>Circle</code> and <code>Rectangle</code>) inherit from the <code>Shape</code> class and provide their own implementations of <code>CalculateArea()</code>.</p>
<p>Adding a new shape, such as a triangle, would involve creating a new class – <em>extending</em> the codebase – that inherits from <code>Shape</code> and implements <code>CalculateArea()</code>, without <em>modifying</em> existing code. This adheres to the OCP by allowing for extension without modification.</p>
<p>Being able to add functionality without modifying existing code means that we don’t have to worry as much about breaking existing working code and introducing bugs.</p>
<p>Following the OCP encourages us to design our software so that we add new features only by adding new code. This helps us to build loosely-coupled, maintainable software.</p>
<h2 id="heading-liskov-substitution-principle-lsp-in-c">Liskov Substitution Principle (LSP) in C</h2>
<blockquote>
<p>Objects of a superclass should be replaceable with objects of its subclass without affecting the correctness of the program.</p>
</blockquote>
<p>This principle ensures that inheritance hierarchies are well-designed and that subclasses adhere to the contracts defined by their superclasses.</p>
<p>Violations of the LSP can lead to unexpected behavior or errors when substituting objects, making code harder to reason about and maintain.</p>
<p>Let's consider an example involving a <code>Rectangle</code> class and a <code>Square</code> class, which inherit from a common <code>Shape</code> class. Initially, we'll violate the LSP by not adhering to the behavior expected from these classes. Then, we'll fix it to ensure that the principle is respected.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Shape</span>
{
 <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">double</span> Area { <span class="hljs-keyword">get</span>; }
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Rectangle</span> : <span class="hljs-title">Shape</span>
{
 <span class="hljs-keyword">public</span> <span class="hljs-keyword">virtual</span> <span class="hljs-keyword">double</span> Width { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

 <span class="hljs-keyword">public</span> <span class="hljs-keyword">virtual</span> <span class="hljs-keyword">double</span> Height { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

 <span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">double</span> Area =&gt; Width * Height;
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Square</span> : <span class="hljs-title">Rectangle</span>
{
 <span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">double</span> Width
 {
   <span class="hljs-keyword">get</span> =&gt; <span class="hljs-keyword">base</span>.Width;
   <span class="hljs-keyword">set</span> =&gt; <span class="hljs-keyword">base</span>.Width = <span class="hljs-keyword">base</span>.Height = <span class="hljs-keyword">value</span>;
 }

 <span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">double</span> Height
 {
   <span class="hljs-keyword">get</span> =&gt; <span class="hljs-keyword">base</span>.Height;
   <span class="hljs-keyword">set</span> =&gt; <span class="hljs-keyword">base</span>.Height = <span class="hljs-keyword">base</span>.Width = <span class="hljs-keyword">value</span>;
 }
}
</code></pre>
<p>Now, let’s test out if <code>Rectangle</code> calculates its area correctly:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Program.cs</span>

<span class="hljs-keyword">var</span> rect = <span class="hljs-keyword">new</span> Rectangle();
rect.Height = <span class="hljs-number">10</span>;
rect.Width = <span class="hljs-number">5</span>;

System.Console.WriteLine(<span class="hljs-string">"Expected area = 10 * 5 = 50."</span>);

System.Console.WriteLine(<span class="hljs-string">"Calculated area = "</span> + rect.Area);
</code></pre>
<p>Running the program:</p>
<pre><code class="lang-plaintext">Expected area = 10 * 5 = 50.

Calculated area = 50
</code></pre>
<p>Perfect!</p>
<p>Now, in our program, the <code>Square</code> class inherits from, or extends, the <code>Rectangle</code> class, because, mathematically, a square is just a special type of rectangle, where its height equals its width. Because of this, we decided that <code>Square</code> should extend <code>Rectangle</code> – it’s like saying “a square <em>is a</em> (special type of) rectangle”.</p>
<p>But look what happens if we substitute the <code>Rectangle</code> class for the <code>Square</code> class:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">var</span> rect = <span class="hljs-keyword">new</span> Square();
rect.Height = <span class="hljs-number">10</span>;
rect.Width = <span class="hljs-number">5</span>;

System.Console.WriteLine(<span class="hljs-string">"Expected area = 10 * 5 = 50."</span>);

System.Console.WriteLine(<span class="hljs-string">"Calculated area = "</span> + rect.Area);
</code></pre>
<pre><code class="lang-plaintext">Expected area = 10 * 5 = 50.

Calculated area = 25
</code></pre>
<p>Oh dear, LSP has been violated: we replaced the object of a superclass (<code>Rectangle</code>) with an object of its subclass (<code>Square</code>), and it affected the correctness of our program. By modeling <code>Square</code> as a subclass of <code>Rectangle</code>, and allowing width and height to be independently set, we violate the LSP. When setting the width and height of a <code>Square</code>, it should retain its squareness, but our implementation allows for inconsistency.</p>
<p>Let’s fix this to satisfy LSP:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Shape</span>
{
 <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">double</span> Area { <span class="hljs-keyword">get</span>; }
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Rectangle</span> : <span class="hljs-title">Shape</span>
{
 <span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> Width { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

 <span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> Height { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

 <span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">double</span> Area =&gt; Width * Height;
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Square</span> : <span class="hljs-title">Shape</span>
{
 <span class="hljs-keyword">private</span> <span class="hljs-keyword">double</span> sideLength;

 <span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> SideLength
 {
   <span class="hljs-keyword">get</span> =&gt; sideLength;
   <span class="hljs-keyword">set</span>
   {
     sideLength = <span class="hljs-keyword">value</span>;
   }
 }

 <span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">double</span> Area =&gt; sideLength * sideLength;
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-comment">// Program.cs</span>

Shape rectangle = <span class="hljs-keyword">new</span> Rectangle { Width = <span class="hljs-number">5</span>, Height = <span class="hljs-number">4</span> };

Console.WriteLine(<span class="hljs-string">$"Area of the rectangle: <span class="hljs-subst">{rectangle.Area}</span>"</span>);

Shape square = <span class="hljs-keyword">new</span> Square { SideLength = <span class="hljs-number">5</span> };

Console.WriteLine(<span class="hljs-string">$"Area of the square: <span class="hljs-subst">{square.Area}</span>"</span>);
</code></pre>
<p>In this corrected example, we redesign the <code>Square</code> class to directly set the side length. Now, a <code>Square</code> is correctly modeled as a subclass of <code>Shape</code>, and it adheres to the Liskov Substitution Principle.</p>
<p>How does this satisfy LSP? Well, we have a superclass, <code>Shape</code>, and subclasses <code>Rectangle</code> and <code>Square</code>. Both <code>Rectangle</code> and <code>Square</code> maintain the correct expected behavior of a <code>Shape</code> — we can substitute a square for a rectangle and the area will still be calculated correctly.</p>
<h2 id="heading-interface-segregation-principle-isp-in-c">Interface Segregation Principle (ISP) in C</h2>
<blockquote>
<p>Clients should not be forced to depend on interfaces they do not use.</p>
</blockquote>
<p>This principle encourages the creation of fine-grained interfaces that contain only the methods required by the clients that use them. It helps to prevent the creation of "fat" interfaces that force clients to implement unnecessary methods, leading to cleaner and more maintainable code.</p>
<p>Let's consider an example involving 2D and 3D shapes, initially violating the ISP.</p>
<p><strong>Violating ISP:</strong></p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">IShape</span>
{
 <span class="hljs-function"><span class="hljs-keyword">double</span> <span class="hljs-title">Area</span>(<span class="hljs-params"></span>)</span>;
 <span class="hljs-function"><span class="hljs-keyword">double</span> <span class="hljs-title">Volume</span>(<span class="hljs-params"></span>)</span>; <span class="hljs-comment">// problem: 2D shapes don't have volume!</span>
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Circle</span> : <span class="hljs-title">IShape</span>
{
 <span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> Radius { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">Area</span>(<span class="hljs-params"></span>)</span>
 {
   <span class="hljs-keyword">return</span> Math.PI * Math.Pow(Radius, <span class="hljs-number">2</span>);
 }

 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">Volume</span>(<span class="hljs-params"></span>)</span>
 {
   <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> InvalidOperationException(<span class="hljs-string">"Volume not applicable for 2D shapes."</span>);
 }
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Sphere</span> : <span class="hljs-title">IShape</span>
{
 <span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> Radius { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">Area</span>(<span class="hljs-params"></span>)</span>
 {
   <span class="hljs-keyword">return</span> <span class="hljs-number">4</span> * Math.PI * Math.Pow(Radius, <span class="hljs-number">2</span>);
 }

 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">Volume</span>(<span class="hljs-params"></span>)</span>
 {
   <span class="hljs-keyword">return</span> (<span class="hljs-number">4.0</span> / <span class="hljs-number">3.0</span>) * Math.PI * Math.Pow(Radius, <span class="hljs-number">3</span>);
 }
}
</code></pre>
<p>In this example, we have an <code>IShape</code> interface representing both 2D and 3D shapes. However, the <code>Volume()</code> method is problematic for 2D shapes, like <code>Circle</code> and <code>Rectangle</code>, because they don't have volume. This violates the ISP because clients (classes using the <code>IShape</code> interface) may be forced to depend on methods they do not need.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">var</span> circle = <span class="hljs-keyword">new</span> Circle();
circle.Radius = <span class="hljs-number">10</span>;

System.Console.WriteLine(circle.Area());
System.Console.WriteLine(circle.Volume()); <span class="hljs-comment">// My text editor doesn't flag a problem...</span>

<span class="hljs-keyword">var</span> sphere = <span class="hljs-keyword">new</span> Sphere();
sphere.Radius = <span class="hljs-number">10</span>;

System.Console.WriteLine(sphere.Area());
System.Console.WriteLine(sphere.Volume());
</code></pre>
<p>Usually, if I try to call a method on an object that doesn’t exist, VS Code will tell me that I’m making a mistake. But above, when I call <code>circle.Volume()</code>, VS code is like “no problem”. And VS code is correct, because the <code>IShape</code> interface forces <code>Circle</code> to implement a <code>Volume()</code> method, even though circles don’t have volume.</p>
<p>It’s easy to see how violating ISP can introduce bugs into a program – above, everything looks fine, until we run the program and an exception gets thrown.</p>
<p><strong>Fixing ISP</strong></p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">IShape2D</span>
{
 <span class="hljs-function"><span class="hljs-keyword">double</span> <span class="hljs-title">Area</span>(<span class="hljs-params"></span>)</span>;
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">IShape3D</span>
{
 <span class="hljs-function"><span class="hljs-keyword">double</span> <span class="hljs-title">Area</span>(<span class="hljs-params"></span>)</span>;
 <span class="hljs-function"><span class="hljs-keyword">double</span> <span class="hljs-title">Volume</span>(<span class="hljs-params"></span>)</span>;
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Circle</span> : <span class="hljs-title">IShape2D</span>
{
 <span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> Radius { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">Area</span>(<span class="hljs-params"></span>)</span>
 {
   <span class="hljs-keyword">return</span> Math.PI * Math.Pow(Radius, <span class="hljs-number">2</span>);
 }
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Sphere</span> : <span class="hljs-title">IShape3D</span>
{
 <span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> Radius { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">Area</span>(<span class="hljs-params"></span>)</span>
 {
   <span class="hljs-keyword">return</span> <span class="hljs-number">4</span> * Math.PI * Math.Pow(Radius, <span class="hljs-number">2</span>);
 }

 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">Volume</span>(<span class="hljs-params"></span>)</span>
 {
   <span class="hljs-keyword">return</span> (<span class="hljs-number">4.0</span> / <span class="hljs-number">3.0</span>) * Math.PI * Math.Pow(Radius, <span class="hljs-number">3</span>);
 }
}
</code></pre>
<p>In the fixed example, we've <em>segregated</em> the <code>IShape</code> interface into two smaller, more focused interfaces: <code>IShape2D</code> and <code>IShape3D</code>. Each shape class now implements only the interface that is relevant to its functionality.</p>
<p>This adheres to the Interface Segregation Principle by ensuring that clients are not forced to depend on methods that they do not use. Clients can now depend only on the interfaces that they need, promoting better code reuse and flexibility.</p>
<p>Next up, the fifth and final SOLID principle…</p>
<h2 id="heading-dependency-inversion-principle-dip-in-c">Dependency Inversion Principle (DIP) in C</h2>
<blockquote>
<p>High-level modules should not depend on low-level modules. Both should depend on abstractions.</p>
</blockquote>
<p>Dependency Inversion is the strategy of depending upon interfaces or abstract classes rather than upon concrete classes. This principle promotes decoupling between modules and promotes the use of interfaces or abstract classes to define dependencies, allowing for more flexible and testable code.</p>
<p>Let's start with an example violating the DIP and then we’ll correct it.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Engine</span> <span class="hljs-comment">// Engine is our "low-level" module</span>
{
 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Start</span>(<span class="hljs-params"></span>)</span>
 {
   System.Console.WriteLine(<span class="hljs-string">"Engine started."</span>);
 }
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Car</span> <span class="hljs-comment">// Car is our "high-level" module</span>
{
 <span class="hljs-keyword">private</span> Engine engine;

 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Car</span>(<span class="hljs-params"></span>)</span>
 {
   <span class="hljs-keyword">this</span>.engine = <span class="hljs-keyword">new</span> Engine(); <span class="hljs-comment">// Direct dependency on concrete Engine class</span>
 }

 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">StartCar</span>(<span class="hljs-params"></span>)</span>
 {
   engine.Start();
   System.Console.WriteLine(<span class="hljs-string">"Car started."</span>);
 }
}
</code></pre>
<p>In this example:</p>
<ul>
<li><p>The <code>Car</code> class directly creates an instance of the <code>Engine</code> class, leading to a tight coupling between Car and Engine.</p>
</li>
<li><p>If the <code>Engine</code> class changes, it may affect the <code>Car</code> class, violating the Dependency Inversion Principle.</p>
</li>
</ul>
<p>The UML diagram below shows that <code>Car</code> depends on <code>Engine</code>:</p>
<p><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXdbd6IZ4TfDmGCPIjsJJHTtEw7_WBxCP-H1cSme78Ze7qJq0fG6tQzNo7A-IbgnnruAZwMBhjuJoozA0rzA9RM35Pu9vWpk4I2Hp6Szk7Ns_kTFbu2oIIfHQa9ceBembsjN8EUlZLkQuB863NyzeeSn7qY?key=p75tPpeumlH4kqsSJuxz6w" alt="AD_4nXdbd6IZ4TfDmGCPIjsJJHTtEw7_WBxCP-H1cSme78Ze7qJq0fG6tQzNo7A-IbgnnruAZwMBhjuJoozA0rzA9RM35Pu9vWpk4I2Hp6Szk7Ns_kTFbu2oIIfHQa9ceBembsjN8EUlZLkQuB863NyzeeSn7qY?key=p75tPpeumlH4kqsSJuxz6w" width="600" height="400" loading="lazy"></p>
<p>But what do we mean by “high level” and “low level” classes?</p>
<p><strong>High-Level Class</strong>: The high-level class is typically the one that represents the main functionality or business logic of the application. It orchestrates the interaction between various components and is often more abstract in nature.</p>
<p>In this example, the <code>Car</code> class can be considered the high-level class. It represents the main functionality related to starting the car and driving it. The <code>Car</code> class is concerned with the overall behavior of the car, such as controlling its movement.</p>
<p><strong>Low-Level Class</strong>: The low-level class is usually one that provides specific functionality or services that are used by the high-level class. It typically deals with implementation details and is more concrete in nature.</p>
<p>In this example, the <code>Engine</code> class can be considered the low-level class. It provides the specific functionality related to starting the engine. The <code>Engine</code> class encapsulates the details of how the engine operates, such as ignition and combustion.</p>
<p>So in summary, the <code>Car</code> class is the high-level class, representing the main functionality of the application related to the car's behavior.</p>
<p>The <code>Engine</code> class is the low-level class, providing specific functionality related to the operation of the engine, which is used by the Car class.</p>
<p><strong>Fixing DIP:</strong></p>
<p>To adhere to the Dependency Inversion Principle, we introduce an abstraction (interface) between <code>Car</code> and <code>Engine</code>, allowing <code>Car</code> to depend on an abstraction instead of a concrete implementation.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">IEngine</span>
{
 <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">Start</span>(<span class="hljs-params"></span>)</span>;
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Engine</span> : <span class="hljs-title">IEngine</span>
{
 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Start</span>(<span class="hljs-params"></span>)</span>
 {
   System.Console.WriteLine(<span class="hljs-string">"Engine started."</span>);
 }
}
</code></pre>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Car</span>
{
 <span class="hljs-keyword">private</span> IEngine engine;

 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Car</span>(<span class="hljs-params">IEngine engine</span>)</span>
 {
   <span class="hljs-keyword">this</span>.engine = engine;
 }

 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">StartCar</span>(<span class="hljs-params"></span>)</span>
 {
   engine.Start();
   System.Console.WriteLine(<span class="hljs-string">"Car started."</span>);
 }
}
</code></pre>
<p>We can now <em>inject</em> any type of engine into <code>Car</code> implementations:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">var</span> engine = <span class="hljs-keyword">new</span> Engine(); <span class="hljs-comment">// concrete implementation to be "injected" into the car</span>

<span class="hljs-keyword">var</span> car = <span class="hljs-keyword">new</span> Car(engine);

car.StartCar();
</code></pre>
<p>From the UML diagram below, we can see that both objects now depend on the abstraction level of the interface. <code>Engine</code> has inverted its dependency on <code>Car</code>.</p>
<p><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXf2Wes5g5HoeLNGoo4weo-gO6AVdVJ1WbRZxUfTEXIFROup8qCeUiQ8l5CsrwXkC5I1_0i3Q5DyzN5wpXSgjol2_RNFysFKpjMyj4SdEI2lFOplOs-uCUxZGEWE9fI4sFzMKfQOvOx33HKViFcXoqTVmi2s2FcLvCobCCZAvA?key=hfr-bV5v9p97pXexBFuY1A" alt="AD_4nXf2Wes5g5HoeLNGoo4weo-gO6AVdVJ1WbRZxUfTEXIFROup8qCeUiQ8l5CsrwXkC5I1_0i3Q5DyzN5wpXSgjol2_RNFysFKpjMyj4SdEI2lFOplOs-uCUxZGEWE9fI4sFzMKfQOvOx33HKViFcXoqTVmi2s2FcLvCobCCZAvA?key=hfr-bV5v9p97pXexBFuY1A" width="600" height="400" loading="lazy"></p>
<p>In this corrected example:</p>
<ol>
<li><p>We define an interface <code>IEngine</code> representing the behavior of an engine.</p>
</li>
<li><p>The <code>Engine</code> class implements the <code>IEngine</code> interface.</p>
</li>
<li><p>The <code>Car</code> class now depends on the <code>IEngine</code> interface instead of the concrete <code>Engine</code> class.</p>
</li>
<li><p>Dependency injection is used to inject the <code>IEngine</code> implementation into the <code>Car</code> class, promoting loose coupling. Now, if we want to give a car a different type of engine, for example a <code>FastEngine</code>, we can inject that in instead. </p>
</li>
<li><p>Now, if the implementation of the engine changes, it won't affect the <code>Car</code> class as long as it adheres to the <code>IEngine</code> interface.</p>
</li>
</ol>
<p>Dependency Injection (DI) offers several advantages in software development:</p>
<ul>
<li><p><strong>Decoupling</strong>: DI promotes loose coupling between components by removing direct dependencies. Components rely on abstractions rather than concrete implementations, making them more independent and easier to maintain.</p>
</li>
<li><p><strong>Testability</strong>: Dependency injection simplifies unit testing by allowing components to be easily replaced with mock or stub implementations during testing. This enables isolated testing of individual components without relying on their dependencies.</p>
</li>
<li><p><strong>Flexibility</strong>: DI provides flexibility in configuring and swapping dependencies at runtime. It allows different implementations of dependencies to be used interchangeably without modifying the client code, facilitating runtime customization and extensibility.</p>
</li>
<li><p><strong>Readability and Maintainability</strong>: By explicitly specifying dependencies in the constructor or method parameters, DI improves code readability and makes the codebase easier to understand. It also reduces the risk of hidden dependencies, leading to more maintainable and understandable code.</p>
</li>
<li><p><strong>Reusability</strong>: DI promotes component reusability by decoupling them from their specific contexts or environments. Components can be designed to be independent of the application framework or platform, making them more portable and reusable in different projects or scenarios.</p>
</li>
<li><p><strong>Scalability</strong>: DI simplifies the management of dependencies in large-scale applications by providing a standardised approach for dependency resolution. It helps prevent dependency hell and makes it easier to manage and scale complex systems.</p>
</li>
</ul>
<p>Overall, dependency injection enhances modularity, testability, and maintainability of software systems, contributing to improved software quality and developer productivity.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Congratulations – you now understand the extremely important SOLID principles. These principles are going to save you a lot of headaches during your software development career, and guide you towards creating beautiful, maintainable, flexible, testable software.</p>
<p>If you’d like to take your software development skills to the next level and learn:</p>
<ul>
<li><p>OOP principles: encapsulation, abstraction, inheritance, polymorphism, coupling, composition, composition vs inheritance, fragile base class problem.</p>
</li>
<li><p>All 23 design patterns (“The Gang of Four Design Patterns”) with real world examples.</p>
</li>
<li><p>Unified Modeling Language (UML): the standard way to model classes and the relationships between them.</p>
</li>
</ul>
<p>Then check out my book:</p>
<p><a target="_blank" href="https://www.amazon.com/Mastering-Design-Patterns-Beginner-Friendly-Principles/dp/B0DBZGQZMZ">Mastering Design Patterns in C#: A Beginner-Friendly Guide, Including OOP and SOLID Principles on Amazon</a> (also available on <a target="_blank" href="https://doabledanny.gumroad.com/l/ennyj">Gumroad</a>).</p>
<p>Hopefully this article helps you to become a better OOP software developer!</p>
<p>Thanks for reading,</p>
<p><a target="_blank" href="https://www.youtube.com/channel/UC0URylW_U4i26wN231yRqvA">Danny</a> 😎</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Object Relational Mapping in Node.js – Optimize Database Interactions With Sequelize ORM ]]>
                </title>
                <description>
                    <![CDATA[ Databases play a vital role in the development of applications across mobile and web platforms. Adequate knowledge of data interactions between the application structure and the database is essential for storing relevant application data. Object-rela... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/object-relational-mapping-in-nodejs-with-sequelize-orm/</link>
                <guid isPermaLink="false">670fa2e2c038b5fdec128d46</guid>
                
                    <category>
                        <![CDATA[ database ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Object Oriented Programming ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Oluwatobi ]]>
                </dc:creator>
                <pubDate>Wed, 16 Oct 2024 11:26:26 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1728644693143/667b7624-6dc2-407a-828b-f5b6c1844ac8.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Databases play a vital role in the development of applications across mobile and web platforms. Adequate knowledge of data interactions between the application structure and the database is essential for storing relevant application data.</p>
<p>Object-relational mapping, as a programming concept, is an efficient standard protocol for facilitating seamless connection with databases. But what does it really mean, and how do you set it up as a developer? We’ll answer these questions and highlight more about object-relational mapping.</p>
<p>Here are the prerequisites:</p>
<ul>
<li><p>Knowledge of Node.js</p>
</li>
<li><p>Use the Express framework</p>
</li>
<li><p>An installed MySQL database</p>
</li>
</ul>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-table-of-contents">Table of Contents</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-an-orm">What is an ORM?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-your-nodejs-server">How to Set Up Your Node.js Server</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-integrate-relevant-packages">How to Integrate Relevant Packages</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-demo-project">Demo Project</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-additional-information">Additional Information</a></p>
</li>
</ul>
<h2 id="heading-what-is-an-orm">What is an ORM?</h2>
<p>Object Relational Mapping (ORM) is a database communication concept in programming that involves the abstraction of data types as compatible object-oriented programming variables. It simply eliminates the use of database-defined queries and storage types to allow ease of creating databases via the programming languages.</p>
<p>Its use has been widely adopted in the tech space as has more advantages than conventional database query methods. Here are some of them:</p>
<ul>
<li><p>It reduces the risk of data manipulation: SQL and non-SQL injections involve inputting malicious SQL syntaxes and queries into the database, which can compromise database security. Having an ORM in place adds an input validation scheme feature, and details the expected input variable syntax and processes it accordingly.</p>
</li>
<li><p>Ease of database communication: ORM serves to simplify the use of databases as a data tool without undergoing the process of learning a different database query language. The ORM schema can be highlighted in an object-oriented fashion in the application language and can be configured to automatically translate the code to queries compatible with the database.</p>
</li>
<li><p>This feature also allows easy code portability, achieving maintenance of a single database integration code base while changing the database without any adverse outcome. It is highly flexible and can be used in any database of choice.</p>
</li>
<li><p>It also has additional features included to allow database interactions. Database migration features and version control processes are provided. With these, we have seen some of its benefits, we will then highlight popular ORM tools used globally.</p>
</li>
</ul>
<p>Here are the popular ORM tools:</p>
<ul>
<li><p><a target="_blank" href="https://docs.sqlalchemy.org/">SQLAlchemy</a></p>
</li>
<li><p><a target="_blank" href="https://www.prisma.io/">Prisma ORM</a></p>
</li>
<li><p><a target="_blank" href="https://sequelize.org/">Sequelize</a></p>
</li>
<li><p><a target="_blank" href="https://guides.rubyonrails.org/active_record_basics.html">ActiveRecord</a></p>
</li>
<li><p><a target="_blank" href="https://typeorm.io/">TypeORM</a></p>
</li>
<li><p><a target="_blank" href="https://sailsjs.com/documentation/reference/waterline-orm">Waterline</a></p>
</li>
</ul>
<p>For this article, we’ll be streamlining our ORM use cases to a basic Node.js project linked to a MySQL database. We’ll use the Sequelize ORM as the tool of choice.</p>
<p>With an average package download of 8.5 million monthly and an active development community, Sequelize boasts robust features that seamlessly integrate databases with backend applications. It also provides a user oriented documentation which helps guide the user on setting up and using the tool.</p>
<p>Here is a link to <a target="_blank" href="https://sequelize.org/docs/v6/getting-started/">the documentation</a>. It also offers support for MySQL, DB2, and SQLite Microsoft SQL server, and it offers features such as read replication, lazy loading, and efficient database transaction properties.</p>
<p>Next, we’ll set up our web application and install Sequelize to connect us to a MySQL database hosted locally.</p>
<h2 id="heading-how-to-set-up-your-nodejs-server">How to Set Up Your Node.js Server</h2>
<p>In this section you’ll set up our Node server. Navigate to the command line and execute <code>npm init</code>. This command creates a new Node project structure for you.</p>
<p>Next, install the Express package – this will serve as the backend framework. You can do this by running the <code>npm i express</code> command.</p>
<h2 id="heading-how-to-integrate-relevant-packages">How to Integrate Relevant Packages</h2>
<p>For the purpose of this tutorial, we’ll install the Sequelize Node package manager in our Node application in order to set up the ORM communication to the database.</p>
<p>To set this up, execute <code>npm i sequelize</code>.</p>
<p>We’ll use a locally hosted MySQL database. To do this, we’ll install an npm package database driver. In this case, we will be installing <code>mysql2</code>. Here is a link to the <a target="_blank" href="https://www.npmjs.com/package/sequelize"><code>package</code></a></p>
<p>Run <code>npm i mysql2</code> to install it.</p>
<p>Let’s move on to configuring the connection to the database and building our demo project.</p>
<h2 id="heading-demo-project">Demo Project</h2>
<p>In this section we’ll build a simple backend server that performs Create-Read-Update-Delete operations, with the Sequelize library serving as the connection pipeline.</p>
<p>In order to begin the project, we’ll have to set up the database connection for our application. We’ll create a database connection file and set up our database credentials. You can name the file <strong>SequelizeConfig</strong>.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {

    <span class="hljs-attr">HOST</span>: <span class="hljs-string">"localhost"</span>,

    <span class="hljs-attr">USER</span>: <span class="hljs-string">"root"</span>,

    <span class="hljs-attr">PASSWORD</span>: <span class="hljs-string">""</span>,

    <span class="hljs-attr">DB</span>: <span class="hljs-string">"sequel"</span>,

    <span class="hljs-attr">dialect</span>: <span class="hljs-string">"mysql"</span>

}
</code></pre>
<p>In the code above, the database credentials were specified, along with the host address. In our case, the database is locally hosted, so localhost is the default host.</p>
<p>The database login details were also provided. The user here is the root, while the password was set to an empty string. This should be tweaked to ensure database security. I also created a defunct database named “sequel”.</p>
<p>The dialect refers to the type of database the user intends to use. In our case, the dialect is MySQL. Note that this can also be replicated on a cloud hosted database with the credentials obtained. With that, let's integrate the connection file with the application.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> SequelConfig = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../config/sequelize'</span>);

<span class="hljs-keyword">const</span> Sequelize = <span class="hljs-built_in">require</span>(<span class="hljs-string">'sequelize'</span>);

<span class="hljs-keyword">const</span> sequelize = <span class="hljs-keyword">new</span> Sequelize(SequelCOnfig.DB, SequelCOnfig.USER, SequelCOnfig.PASSWORD, {

    <span class="hljs-attr">host</span>: SequelCOnfig.HOST,

    <span class="hljs-attr">dialect</span>: SequelCOnfig.dialect

});
</code></pre>
<p>In order to facilitate a connection to the database, the variables in the config file were imported and initialized in the Sequelize setup file.</p>
<pre><code class="lang-javascript">

<span class="hljs-keyword">const</span> db = {};

db.Sequelize = Sequelize;

db.sequelize = sequelize;

db.user = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../model/user.model'</span>)(sequelize, Sequelize);

db.token = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../model/token.model'</span>)(sequelize, Sequelize)

<span class="hljs-built_in">module</span>.exports= db;
</code></pre>
<p>This file above imports the <code>config</code> file created previously and initializes the Sequelize library. The code then fetches the database details inputted in the config file and, when executed, creates the database.</p>
<p>Furthermore, the various database models which will be discussed subsequently are then integrated with the defunct database and generates a SQL database table .</p>
<p>To get this up and running, the database file created is invoked using the <code>sequelize.sync()</code> method. Any error encountered is logged and the database connection gets terminated.</p>
<pre><code class="lang-javascript">db.sequelize.sync().then(<span class="hljs-function">() =&gt;</span> {

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'user created '</span>);

}).catch(<span class="hljs-function"><span class="hljs-params">err</span> =&gt;</span> {

  <span class="hljs-built_in">console</span>.error(err)

})
</code></pre>
<p>We’ll go on to discuss the database models.</p>
<h3 id="heading-models">Models</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> Sequelize = <span class="hljs-built_in">require</span>(<span class="hljs-string">"sequelize"</span>);

<span class="hljs-built_in">module</span>.exports = <span class="hljs-function">(<span class="hljs-params">sequelize</span>) =&gt;</span> {

sequelize.define(

<span class="hljs-string">"user"</span>, {

<span class="hljs-attr">firstName</span>: {

<span class="hljs-attr">type</span> : Sequelize.DataTypes.STRING,

<span class="hljs-attr">allowNull</span> : <span class="hljs-literal">false</span>

},

<span class="hljs-attr">lastName</span>: {

<span class="hljs-attr">type</span> : Sequelize.DataTypes.STRING,

<span class="hljs-attr">allowNull</span> : <span class="hljs-literal">false</span>

},

<span class="hljs-attr">email</span> : {

<span class="hljs-attr">type</span> : Sequelize.DataTypes.STRING,

<span class="hljs-attr">allowNull</span> : <span class="hljs-literal">false</span>, <span class="hljs-attr">unique</span>: <span class="hljs-literal">true</span>

},

<span class="hljs-attr">password</span>: {

<span class="hljs-attr">type</span> : Sequelize.DataTypes.STRING,

<span class="hljs-attr">allowNull</span> : <span class="hljs-literal">false</span>

},

<span class="hljs-attr">role</span>:  {

<span class="hljs-attr">type</span> : Sequelize.DataTypes.STRING,

<span class="hljs-attr">allowNull</span> : <span class="hljs-literal">false</span>

}

}

)

}
</code></pre>
<p>In the code above, the user model was initialized in Sequelize ORM and the field details were specified: <code>email</code>, <code>role</code>, <code>lastName</code>, and <code>password</code>. The type of data to be received was also specified.</p>
<p>It also provides an option to ensure the uniqueness of the user details, and the option to prevent the user from leaving some fields empty via the use of <code>allowNull = false</code>.</p>
<p>On execution of the application, the Sequelize ORM creates an SQL equivalent of the model as a data table.</p>
<p>Next, we’ll work on the CRUD functions in Node.js.</p>
<h3 id="heading-create-operation">Create Operation</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> createUser = <span class="hljs-keyword">async</span> (userInfo) =&gt; {

<span class="hljs-keyword">try</span> {

<span class="hljs-comment">// Check if the email already exists in the database</span>

<span class="hljs-keyword">const</span> ifEmailExists = <span class="hljs-keyword">await</span> User.findOne({ <span class="hljs-attr">where</span>: { <span class="hljs-attr">email</span>: userInfo.email } });

<span class="hljs-keyword">if</span> (ifEmailExists) {

<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ApiError(<span class="hljs-string">'Email has already been registered'</span>);

}

<span class="hljs-comment">// Create the new user</span>

<span class="hljs-keyword">const</span> newUser = <span class="hljs-keyword">await</span> User.create(userInfo);

<span class="hljs-keyword">return</span> newUser; <span class="hljs-comment">// Return the created user object</span>

} <span class="hljs-keyword">catch</span> (error) {

<span class="hljs-comment">// Handle errors such as validation or uniqueness constraint</span>

<span class="hljs-keyword">throw</span> error;

}

};
</code></pre>
<p>The function above highlights the controller function for creating user entries in the Express server.</p>
<p>The function is asynchronous, which allows for execution of some commands before eventual execution. The code ensures that the user email doesn’t exist in the database before cresting a new user.</p>
<p>In addition, we also ensured that each email field is unique. If the user details are entered into the database successfully, a “successful” response is sent back to the server. Additionally, any error encountered leads to termination of the function and the error gets sent back to the server.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728593905405/ae2b4fb6-0dfd-4e68-890b-a5d1afc88d71.png" alt="A POST request to create a new user endpoint" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-read-operation">Read Operation</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> FetchUser = <span class="hljs-keyword">async</span> (userId) =&gt; {

<span class="hljs-keyword">let</span> userDets;

<span class="hljs-keyword">if</span> (userId) {

<span class="hljs-comment">// Fetch a single user by ID if userId is provided</span>

userDets = <span class="hljs-keyword">await</span> User.findOne({ <span class="hljs-attr">where</span>: { <span class="hljs-attr">id</span>: userId } });

<span class="hljs-comment">// Check if the user exists</span>

<span class="hljs-keyword">if</span> (!userDets) {

<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ApiError(httpStatus.NOT_FOUND, <span class="hljs-string">'User not found'</span>);

}

} <span class="hljs-keyword">else</span> {

<span class="hljs-comment">// Fetch all users if no userId is provided</span>

userDets = <span class="hljs-keyword">await</span> User.findAll();

<span class="hljs-comment">// Check if any users were found</span>

<span class="hljs-keyword">if</span> (userDets.length === <span class="hljs-number">0</span>) {

<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ApiError(httpStatus.NOT_FOUND, <span class="hljs-string">'No users found'</span>);

}

}
</code></pre>
<p>The read operation fetches the desired query and sends it back to the user without modification. The user ID, which should be unique, is used to search for a specific user. In this scenario, we want access to all the users created in the database.</p>
<p>In case the requested query is not found, an appropriate error code is generated.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728593791809/3e4dae9d-98ad-4966-b17a-b9649c41921d.png" alt="A GET request  to fetch all the users in the database endpoint" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-update-operation">Update Operation</h3>
<pre><code class="lang-javascript">

<span class="hljs-keyword">const</span> updateUser = <span class="hljs-keyword">async</span> (userId, userDetails) =&gt; {

<span class="hljs-comment">// First, find the user by their ID</span>

<span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> User.findOne({ <span class="hljs-attr">where</span>: { <span class="hljs-attr">id</span>: userId } });

<span class="hljs-keyword">if</span> (!user) {

<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ApiError(httpStatus.BAD_REQUEST, <span class="hljs-string">"User doesn't exist"</span>);

}

<span class="hljs-comment">// Update the user with the new details</span>

<span class="hljs-keyword">await</span> User.update(userDetails, { <span class="hljs-attr">where</span>: { <span class="hljs-attr">id</span>: userId } });

<span class="hljs-comment">// Fetch the updated user to return it</span>

<span class="hljs-keyword">const</span> updatedUser = <span class="hljs-keyword">await</span> User.findOne({ <span class="hljs-attr">where</span>: { <span class="hljs-attr">id</span>: userId } });

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Updated user:'</span>, updatedUser); <span class="hljs-comment">// Log the updated user</span>

<span class="hljs-keyword">return</span> updatedUser; <span class="hljs-comment">// Return the updated user object</span>

};
</code></pre>
<p>The update operation aims to modify the data entered in previous operations. That is, to update some data fields.</p>
<p>In the case of Sequelize, the <code>update</code> method is invoked. To succeed with this, the particular user to be edited must be identified. The code above then generates the updated data field and sends it as the output of a successful request.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728593828831/33a2bf88-7f4c-4847-b139-e4d97dcd805b.png" alt="A PUT request to edit and update user details endpoint" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h3 id="heading-delete-operation">Delete Operation</h3>
<pre><code class="lang-javascript">

<span class="hljs-keyword">const</span> deleteUser = <span class="hljs-keyword">async</span> (userId) =&gt; {

<span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> User.findOne({ <span class="hljs-attr">where</span>: { <span class="hljs-attr">id</span>: userId } });

<span class="hljs-keyword">if</span> (!user) {

<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ApiError(httpStatus.BAD_REQUEST, <span class="hljs-string">"User doesn't exist"</span>);

}

<span class="hljs-comment">// Delete the user</span>

<span class="hljs-keyword">await</span> user.destroy();

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Deleted user:'</span>, user); <span class="hljs-comment">// Log the deleted user</span>

<span class="hljs-keyword">return</span> user; <span class="hljs-comment">// Return the deleted user object (useful for confirmation)</span>

};
</code></pre>
<p>The delete operation is invoked when data in the database table needs to be deleted. Sequelize makes provision for this via the use of the <code>destroy</code> method. This method deletes a specific user. When executed, a success response code is displayed.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728593876348/ad01b671-5e93-4e34-afbb-dc2a961d576e.png" alt="A DELETE request to remove a particular user detail from the database" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-additional-information">Additional Information</h2>
<p>So far, we have integrated an ORM library to serve as a connection between our backend application and our relational database. We also explored advanced concepts such as database migrations and CRUD operations. To learn more about this, you can explore the documentation and utilize it in building more complex projects, as hands-on learning is much encouraged.</p>
<p>Feel free to reach out to me on my <a target="_blank" href="http://dev.to/oluwatobi2001">blog</a> and check out my other articles <a target="_blank" href="https://linktr.ee/tobilyn77">here</a>. Till next time, keep on coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Write Cleaner Code Using Mongoose Schemas ]]>
                </title>
                <description>
                    <![CDATA[ If you are used to building NodeJS applications using the Mongoose ORM, this article is for you. In it, we'll discuss some cool features of Mongoose schemas that'll help you write more organized and maintainable code. To get the most out of this guid... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-write-cleaner-code-using-mongoose-schemas/</link>
                <guid isPermaLink="false">66db07581905f28bb66717a2</guid>
                
                    <category>
                        <![CDATA[ mongoose ]]>
                    </category>
                
                    <category>
                        <![CDATA[ clean code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ MongoDB ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Object Oriented Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ dry ]]>
                    </category>
                
                    <category>
                        <![CDATA[ APIs ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ ِAya Nabil Othman ]]>
                </dc:creator>
                <pubDate>Fri, 06 Sep 2024 13:44:56 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1725431278897/86823d79-7b9c-4512-a834-edcdd4e11ac3.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you are used to building NodeJS applications using the Mongoose ORM, this article is for you. In it, we'll discuss some cool features of Mongoose schemas that'll help you write more organized and maintainable code.</p>
<p>To get the most out of this guide, you should have a background in JavaScript, understand how Mongoose works, and know Object-Oriented Programming basics.</p>
<h3 id="heading-heres-what-well-cover">Here's what we'll cover:</h3>
<ol>
<li><p><a class="post-section-overview" href="#heading-what-is-a-mongoose-schema">What is a Mongoose Schema?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-discriminator">Discriminator</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-statics">Statics</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-methods">Methods</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-query-builder">Query Builder</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-hooks">Hooks</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-summary">Summary</a></p>
</li>
</ol>
<h2 id="heading-what-is-a-mongoose-schema">W<strong>hat is a Mongoose Schema?</strong></h2>
<p>Mongoose schemas provide a structured way to model data in a MongoDB database, allowing you to define the properties and behavior of the documents. Schemas serve as a blueprint for a document that gets saved in the database. They enables developers to enforce data integrity and work with MongoDB in a more intuitive and organized manner.</p>
<p>Within a MongoDB collection, a schema outlines the fields of the documents, their data types, validation rules, default values, constraints, and more.</p>
<p>Programmatically, a Mongoose schema is a JavaScript object. Actually, it is an instance of a built-in class called <code>Schema</code> inside the <code>mongoose</code> module. For this reason, you can add more methods to its prototype. This will help you implement many features as middleware, methods, statics, and more. You will learn about some of them in this tutorial.</p>
<h3 id="heading-features-youll-learn-how-to-implement"><strong>Features you'll learn how to implement:</strong></h3>
<ul>
<li><p><a class="post-section-overview" href="#discriminator">Discriminator</a></p>
</li>
<li><p><a class="post-section-overview" href="#statics">Statics</a></p>
</li>
<li><p><a class="post-section-overview" href="#methods">Methods</a></p>
</li>
<li><p><a class="post-section-overview" href="#query-builder">Query Builder</a></p>
</li>
<li><p><a class="post-section-overview" href="#hooks">Hooks</a></p>
</li>
</ul>
<h2 id="heading-discriminator">Discriminator</h2>
<p>A discriminator is a feature that enables you to create multiple models (subtypes) that inherit from a base model (parent). This happens by defining a base schema and then extending it with extra fields specific to each subtype or each child schema.</p>
<p>All documents, regardless of their specific model, are stored in the same MongoDB collection. This keeps your data organized in a single collection while allowing for flexible querying and data management. Also, each document includes a special field that indicates its specific model type, allowing Mongoose to distinguish between the different subtypes.</p>
<p><strong>How to use</strong> <code>discriminator</code><strong>:</strong></p>
<ol>
<li><p>Start by defining a base schema, which will have the common fields among the subtypes. After that, create a model from it.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">import</span> mongoose <span class="hljs-keyword">from</span> <span class="hljs-string">'mongoose'</span>;

 <span class="hljs-keyword">const</span> baseSchema = <span class="hljs-keyword">new</span> mongoose.Schema({
     <span class="hljs-attr">name</span>: { <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>, <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span> },
 }, { <span class="hljs-attr">discriminatorKey</span>: <span class="hljs-string">'kind'</span> }; <span class="hljs-comment">// defaults to '__t');</span>

 <span class="hljs-keyword">const</span> BaseModel = mongoose.model(<span class="hljs-string">'Base'</span>, baseSchema);
</code></pre>
</li>
<li><p>Create the subtypes that extend the base schema by defining the <code>discriminator</code> for each one.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> catSchema = <span class="hljs-keyword">new</span> mongoose.Schema({
     <span class="hljs-attr">meow</span>: { <span class="hljs-attr">type</span>: <span class="hljs-built_in">Boolean</span>, <span class="hljs-attr">default</span>: <span class="hljs-literal">true</span> }
 });
 <span class="hljs-comment">// subtype</span>
 <span class="hljs-keyword">const</span> Cat = BaseModel.discriminator(<span class="hljs-string">'Cat'</span>, catSchema);

 <span class="hljs-keyword">const</span> dogSchema = <span class="hljs-keyword">new</span> mongoose.Schema({
     <span class="hljs-attr">bark</span>: { <span class="hljs-attr">type</span>: <span class="hljs-built_in">Boolean</span>, <span class="hljs-attr">default</span>: <span class="hljs-literal">true</span> }
 });
 <span class="hljs-comment">// subtype</span>
 <span class="hljs-keyword">const</span> Dog = BaseModel.discriminator(<span class="hljs-string">'Dog'</span>, dogSchema);
</code></pre>
</li>
<li><p>You can then create documents in the regular way. All the documents will be stored in the same collection, but each has its own type depending on its subtype model.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> fluffy = <span class="hljs-keyword">await</span> Cat.create({ <span class="hljs-attr">name</span>: <span class="hljs-string">'Fluffy'</span> });
 <span class="hljs-keyword">const</span> rover = <span class="hljs-keyword">await</span> Dog.create({ <span class="hljs-attr">name</span>: <span class="hljs-string">'Rover'</span> });
</code></pre>
</li>
</ol>
<h3 id="heading-discriminator-use-case"><code>discriminator</code> use case:</h3>
<p>Let's say that you're building a multi-user Ecommerce web application which accommodates three main user roles: <em>admins</em>, <em>clients</em>, and <em>sellers</em>. Each of these roles plays a crucial part in the ecosystem of online shopping.</p>
<p>If you try to build a class for each role, you'll find that all the three have common fields and methods. You may decide to create a parent schema (user) and some other children schemas (client, seller, admin) that inherit from it.</p>
<p>You can use the <code>discriminator</code> to achieve this.</p>
<p>In your <code>user.model.js</code> file, add the following code:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> mongoose <span class="hljs-keyword">from</span> <span class="hljs-string">"mongoose"</span>;

<span class="hljs-keyword">const</span> userSchema = mongoose.Schema(
  {
    <span class="hljs-attr">name</span>: <span class="hljs-built_in">String</span>,
    <span class="hljs-attr">profilePic</span>: <span class="hljs-built_in">String</span>,
    <span class="hljs-attr">email</span>: <span class="hljs-built_in">String</span>,
    <span class="hljs-attr">password</span>: <span class="hljs-built_in">String</span>,
    <span class="hljs-attr">birthDate</span>: <span class="hljs-built_in">Date</span>,
    <span class="hljs-attr">accountAcctivated</span>: { <span class="hljs-attr">type</span>: <span class="hljs-built_in">Boolean</span>, <span class="hljs-attr">default</span>: <span class="hljs-literal">false</span> },
  },
  {
    <span class="hljs-attr">timestamps</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">discriminatorKey</span>: <span class="hljs-string">"role"</span>,
  }
);

<span class="hljs-keyword">const</span> User = mongoose.model(<span class="hljs-string">"User"</span>, userSchema);
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> User;
</code></pre>
<p>Now you have the base model (<code>User</code>) from which other subtypes will inherit. In this parent schema, you define the common fields that all users will share regardless of their roles.</p>
<p>In your <code>client.model.js</code> file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> mongoose <span class="hljs-keyword">from</span> <span class="hljs-string">"mongoose"</span>;
<span class="hljs-keyword">import</span> User <span class="hljs-keyword">from</span> <span class="hljs-string">"./user.model.js"</span>;

<span class="hljs-keyword">const</span> clientSchema = mongoose.Schema(
  {
    <span class="hljs-attr">products</span>: <span class="hljs-built_in">Array</span>,
    <span class="hljs-attr">address</span>: <span class="hljs-built_in">String</span>,
    <span class="hljs-attr">phone</span>: <span class="hljs-built_in">String</span>,
  }
);

<span class="hljs-keyword">const</span> Client = User.discriminator(<span class="hljs-string">"Client"</span>, clientSchema);
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Client;
</code></pre>
<p>In your <code>seller.model.js</code> file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> mongoose <span class="hljs-keyword">from</span> <span class="hljs-string">"mongoose"</span>;
<span class="hljs-keyword">import</span> User <span class="hljs-keyword">from</span> <span class="hljs-string">"./user.model.js"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> sellerSchema = mongoose.Schema(
  {
    <span class="hljs-attr">rating</span>: <span class="hljs-built_in">Number</span>,
    <span class="hljs-attr">businessType</span>: { <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>, <span class="hljs-attr">enum</span>: [<span class="hljs-string">"individual"</span>, <span class="hljs-string">"corporation"</span>] },
  }
);

<span class="hljs-keyword">const</span> Seller = User.discriminator(<span class="hljs-string">"Seller"</span>, sellerSchema);
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Seller;
</code></pre>
<p>In your <code>admin.model.js</code> file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> mongoose <span class="hljs-keyword">from</span> <span class="hljs-string">"mongoose"</span>;
<span class="hljs-keyword">import</span> User <span class="hljs-keyword">from</span> <span class="hljs-string">"./user.model.js"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> adminSchema = mongoose.Schema(
  {
    <span class="hljs-attr">permissions</span>: <span class="hljs-built_in">Array</span>,
    <span class="hljs-attr">assignedTasks</span>: <span class="hljs-built_in">Array</span>,
    <span class="hljs-attr">department</span>: <span class="hljs-built_in">String</span>,
  }
);

<span class="hljs-keyword">const</span> Admin = User.discriminator(<span class="hljs-string">"Admin"</span>, adminSchema);
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Admin;
</code></pre>
<p>The subtypes or children will be the <code>Client</code>, <code>Seller</code>, and <code>Admin</code>. In each subtype schema, you should add any extra fields or behaviors specific to this subtype only. By creating the child model using the discriminator, the child model will inherit all the fields and methods of its parent model <code>User</code>.  </p>
<p>So the previous code will create a <code>user</code> collection in the database with each document having a <code>role</code> field either Client, or Seller, or Admin. All documents are now sharing the parent (<code>user</code>) fields, and depending on the <code>role</code> of each document, each has another extra field.</p>
<p>Although all the documents will be saved in one single collection, models are fully separated while coding. What does this mean?</p>
<p>For instance, If you need to retrieve all clients from the <code>User</code> collection, you should write <code>Client.find({})</code>. This statement uses the discriminator key to find all documents whose <code>role</code> is <code>Client</code>. This way, any operations or queries that refer to one of the child models will still be written separately from the parent model.</p>
<p><strong>Note:</strong> Before diving into the next sections, just keep in mind that any statics, methods, query builders, or hooks should be defined before creating the model itself (that is, before <code>const User = mongoose.model("User", userSchema);</code>).</p>
<h2 id="heading-statics">Statics</h2>
<p>Statics are useful for defining functions that operate on the model level. They allow you to define reusable functions for operations related to the entire model. They help encapsulate logic that applies to the model rather than individual documents, making your code cleaner, more organized and maintainable</p>
<p>Methods like <code>find</code>, <code>findOne</code>, <code>findById</code> and others all are methods attached to the model. By using the <code>statics</code> property of Mongoose schemas, you will be able to build your own model method.  </p>
<p>Statics are powerful. By using them, you can encapsulate complex queries that you might want to reuse. Also, you can create statics for operations that modify or aggregate data, such as counting documents or finding documents based on specific criteria.</p>
<h3 id="heading-statics-use-case"><code>statics</code> use case</h3>
<p>Statics are easy to build. You define a static method on your schema using the <code>statics</code> object.</p>
<p>In your <code>user.model.js</code> file, add these static methods, <code>countUsers</code> and <code>findByEmail</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// model method</span>
userSchema.statics.countUsers = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.countDocuments({});
};

<span class="hljs-comment">// model method</span>
userSchema.statics.findByEmail = <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">email</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.findOne({ email });
};
</code></pre>
<p>Inside any static method, <code>this</code> refers to the <strong>model</strong> itself. In this example, <code>this</code> in <code>this.findOne({ email })</code> refers to the <code>User</code> model.</p>
<p>Example usage:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> User.findByEmail(<span class="hljs-string">"foo@bar.com"</span>);
<span class="hljs-comment">//or</span>
<span class="hljs-keyword">const</span> client = <span class="hljs-keyword">await</span> Client.findByEmail(<span class="hljs-string">"foo@bar.com"</span>);
<span class="hljs-comment">//or</span>
<span class="hljs-keyword">const</span> seller = <span class="hljs-keyword">await</span> Seller.findByEmail(<span class="hljs-string">"foo@bar.com"</span>);
<span class="hljs-comment">//or</span>
<span class="hljs-keyword">const</span> admin = <span class="hljs-keyword">await</span> Admin.findByEmail(<span class="hljs-string">"foo@bar.com"</span>);
</code></pre>
<p>When you call the static method on your model, the method gets called and <code>this</code> is replaced by the model you called the statics on. This line performs a query to find a single document in the MongoDB collection where the <code>email</code> field matches the provided <code>email</code> argument.</p>
<h2 id="heading-methods">Methods</h2>
<p>Methods are functions that you can define on a schema and that can be called on instances of documents created from this schema. They help encapsulate logic within the document itself, making your code cleaner and more modular.</p>
<p>By using instance methods, you can easily interact with and manipulate the data associated with specific documents.</p>
<h3 id="heading-methods-use-case"><code>methods</code> use case</h3>
<p>You can define methods on the schema using the <code>methods</code> object.</p>
<p>In your <code>user.model.js</code> file, add a document method through which you can check the password of a user:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// instance or document method</span>
userSchema.methods.getProfile = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> (<span class="hljs-subst">${<span class="hljs-built_in">this</span>.email}</span>)`</span>;
};

<span class="hljs-comment">// instance or document method</span>
userSchema.methods.checkPassword = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">password</span>) </span>{
    <span class="hljs-keyword">return</span> password === <span class="hljs-built_in">this</span>.password ? <span class="hljs-literal">true</span> : <span class="hljs-literal">false</span>;
};
</code></pre>
<p>Inside any document method, <code>this</code> refers to the <strong>document</strong> itself. In this example, <code>this</code> in <code>this.password</code> refers to the <code>user</code> document at which the method will get called on. This means that you can access all the fields of this document. This is so valuable because you can retrieve, modify, and check for anything related to this document.</p>
<p>Example usage:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> client = <span class="hljs-keyword">await</span> Client.findById(...)
client.checkPassword(<span class="hljs-string">"12345"</span>)
<span class="hljs-comment">//or</span>
<span class="hljs-keyword">const</span> seller = <span class="hljs-keyword">await</span> Seller.findById(...)
seller.checkPassword(<span class="hljs-string">"12345"</span>)
<span class="hljs-comment">//or</span>
<span class="hljs-keyword">const</span> admin = <span class="hljs-keyword">await</span> Admin.findById(...)
admin.checkPassword(<span class="hljs-string">"12345"</span>)
</code></pre>
<p>Since methods are instance-level functions, they are called on the documents. <code>await Client.findById(...)</code> will return a document that has all the built-in methods as well as your own predefined methods <code>checkPassword</code> and <code>getProfile</code>. So by calling, for example <code>client.checkPassword("12345")</code>, the <code>this</code> keyword in the <code>checkPassword</code> function definition will get replaced with the <code>client</code> document. This in turn will compare the user password with the password saved earlier in the database.</p>
<h2 id="heading-query-builder">Query Builder</h2>
<p>A query builder in Mongoose is a custom method that you can define on the query object to simplify and encapsulate common query patterns. These query builders allow you to create reusable and readable query logic, making it easier to work with your data.</p>
<p>One of the most valuable usages of query builders is chaining. They can be chained with other query builders that you've built or with standard query methods like find, sort, and so on.</p>
<h3 id="heading-query-builder-use-case">Query builder use case</h3>
<p>You define query builders by adding them to the <code>query</code> property of a Mongoose schema.</p>
<p>In your <code>user.model.js</code> file, add a query helper method that lets you implement pagination.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// query helper</span>
userSchema.query.paginate = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">{ page, limit }</span>) </span>{
    <span class="hljs-comment">// some code</span>
    <span class="hljs-keyword">const</span> skip = limit * (page - <span class="hljs-number">1</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.skip(skip).limit(limit);
};
</code></pre>
<p>To implement pagination, you need two important variables: first, the page number, and second, the number of items you will retrieve per page.</p>
<p>To query the database for a specific count of documents, you will always use the <code>skip</code> and <code>limit</code> built-in query methods in <code>mongoose</code>. <code>skip</code> is used to set a cursor after a certain number of documents, after which the query will get implemented. <code>limit</code> is used to retrieve a specific number of documents.</p>
<p>Inside any query builder method, <code>this</code> refers to the <strong>query</strong> itself. And since query builders are chainable, you can call any of them after each other.</p>
<p>Finally, any query builder method should return a <code>mongoose query object</code>, which is why you must write <code>return this.skip(skip).limit(limit)</code>.</p>
<p>Example usage:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> results = <span class="hljs-keyword">await</span> Client.find().paginate({ <span class="hljs-attr">page</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">limit</span>: <span class="hljs-number">5</span> });
<span class="hljs-comment">//or</span>
<span class="hljs-keyword">const</span> results = <span class="hljs-keyword">await</span> Seller.find().paginate({ <span class="hljs-attr">page</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">limit</span>: <span class="hljs-number">5</span> });
<span class="hljs-comment">//or</span>
<span class="hljs-keyword">const</span> results = <span class="hljs-keyword">await</span> Admin.find().paginate({ <span class="hljs-attr">page</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">limit</span>: <span class="hljs-number">5</span> });
</code></pre>
<p>You can then call it on any query, and <code>await Client.find().paginate({ page: 2, limit: 5 })</code> will invoke the <code>paginate</code> function and replace the <code>this</code> keyword with <code>Client.find()</code> using the query builder.</p>
<p>You can implement pagination with certain conditions, but you'll always call <code>skip</code> and <code>limit</code>. By defining the <code>paginate</code> query builder you won't repeat yourself and you'll be able to encapsulate the logic in one single function.</p>
<h2 id="heading-hooks">Hooks</h2>
<p>Hooks (also known as middleware) are functions that are executed at specific points in the lifecycle of a document. They allow you to add custom behavior before or after certain operations, such as saving, updating, or removing documents.</p>
<p>Types of Hooks</p>
<ul>
<li><p>Pre Hooks: Executed before an operation.</p>
</li>
<li><p>Post Hooks: Executed after an operation.</p>
</li>
</ul>
<h3 id="heading-hooks-use-case">Hooks use case</h3>
<p>In your <code>user.model.js</code> file, add a <code>post</code> save middleware through which you can send an email for account activation once the user document is saved in the database.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// post hook</span>
userSchema.post(<span class="hljs-string">"save"</span>, <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">doc, next</span>) </span>{
  <span class="hljs-comment">// send email logic</span>
  <span class="hljs-comment">// if succeeded</span>
  <span class="hljs-keyword">return</span> next();
  <span class="hljs-comment">// if failed</span>
  <span class="hljs-keyword">return</span> next(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Failed to send email!"</span>));
});
</code></pre>
<p>The callback function will get invoked once you create a user through <code>model.create()</code> or any time you call <code>save()</code> method on the user document.</p>
<p>In this this example, if you need to avoid sending emails on save, you should write a condition to be sure that this <code>save</code> is for a new user only. You can write something like <code>if (doc.createdAt.getTime() === doc.updatedAt.getTime())</code>.</p>
<h3 id="heading-summary"><strong>Summary</strong></h3>
<p>In this overview of Mongoose features, we've explored four key concepts: discriminators, statics, methods, and hooks.</p>
<p><strong>Discriminators</strong> allow you to create multiple models that share a common schema enabling different document types to be stored in a single collection. This facilitates data management and querying.  </p>
<p><strong>Statics</strong> are model-level methods that provide reusable functionality applicable to the entire model. They encapsulate complex queries and data manipulation logic, helping to keep your codebase clean and maintainable.  </p>
<p><strong>Methods</strong> are instance-level functions that operate on individual document instances. They allow for custom behaviors and data manipulations specific to each document, so you can modify the document’s data in a specific way, such as formatting or calculating values based on its fields.  </p>
<p><strong>Hooks</strong> (or middleware) enable you to run functions at specific points in the document lifecycle, such as before or after saving, updating or deleting a document. This is useful for implementing validation, logging, or any other side effects related to database operations.  </p>
<p>Together, these features enhance the versatility and organization of your Mongoose models, making it easier to build robust and maintainable applications with MongoDB.</p>
<p><a target="_blank" href="https://github.com/Ayanabilothman/mongoose-schema-features">Here</a> can will find a repository where you can learn more about Mongoose schemas and use cases.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ A Guide to Object-Oriented Programming Principles ]]>
                </title>
                <description>
                    <![CDATA[ A programming language is generally classified based on its support for one or more paradigms.  Object-oriented programming is one such paradigm, where the code is organized as objects.  It is used to develop desktop and mobile applications or more c... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/a-guide-to-object-oriented-programming-principles/</link>
                <guid isPermaLink="false">66ba1ab52ab35c1de21292f8</guid>
                
                    <category>
                        <![CDATA[ object oriented ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Object Oriented Programming ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Anjan Baradwaj ]]>
                </dc:creator>
                <pubDate>Tue, 18 Jun 2024 09:13:37 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/06/oop-principles.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>A programming language is generally classified based on its support for one or more paradigms. </p>
<p>Object-oriented programming is one such paradigm, where the code is organized as objects. </p>
<p>It is used to develop desktop and mobile applications or more complex web or enterprise applications. </p>
<p>Using object-oriented programming, you can build modular and scalable software that is easy to maintain.</p>
<p>In this article, you will learn about the principles of object-oriented Programming that lay the foundation for building robust systems. </p>
<p>We will use Java as the programming language for the examples provided below.</p>
<h2 id="heading-what-is-object-oriented-programming">What is Object-Oriented Programming?</h2>
<p>Object-Oriented Programming is a programming methodology that models real-world entities in the form of objects. </p>
<p>These objects are instances of classes. </p>
<p>A class can be thought of as a blueprint and each class can contain fields, which define the attributes of the object, and methods, which describe the object's behavior. Each class can be developed, tested, and debugged independently.</p>
<p>Now that you have an understanding of the basic definition of object-oriented programming, let us jump right in and learn about its core principles.</p>
<p>There are four core principles, or pillars, in the object-oriented Programming paradigm. They are:</p>
<ul>
<li>Abstraction</li>
<li>Encapsulation</li>
<li>Inheritance</li>
<li>Polymorphism</li>
</ul>
<p>What do they mean? Let us explore further with a simple explanation followed by an example for each of them in the following sections.</p>
<h2 id="heading-what-is-abstraction">What is Abstraction?</h2>
<p>Abstraction is defined as the concept of hiding the details of implementation and exposing only the necessary functionalities of the object to the user. </p>
<p>The keywords that you need to keep in mind here are: 'Implementation hiding'. </p>
<p>Abstraction in Java can be achieved through Interfaces and Abstract classes.</p>
<pre><code class="lang-java"><span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">makeSomeNoise</span><span class="hljs-params">()</span></span>;
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">makeSomeNoise</span><span class="hljs-params">()</span> </span>{
        System.out.println(<span class="hljs-string">"Bark"</span>);
    }
}

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Main</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        Dog myDog = <span class="hljs-keyword">new</span> Dog();
        myDog.makeSomeNoise(); <span class="hljs-comment">// Output - Bark</span>
    }
}
</code></pre>
<p>In the above example, abstraction is achieved with the help of an abstract class named <code>Animal</code>. </p>
<p>Here, only the necessary functionality of the class is exposed via the <code>makeSomeNoise()</code> method. </p>
<p>The details of implementation are hidden in the abstract class and they are only provided in the concrete class <code>Dog</code>, which extends the <code>Animal</code> class. </p>
<p>Note that you will learn more about the <code>extends</code> keyword while we discuss Inheritance.</p>
<h2 id="heading-what-is-encapsulation">What is Encapsulation?</h2>
<p>Encapsulation refers to the concept of encapsulating or wrapping up the member variables (data) and the methods (behavior) of an object into a single unit, such as a class. </p>
<p>The internal information of the object is hidden so that we can prevent unintended modifications and allow only controlled access. The keywords that you need to keep in mind here are: 'Information hiding'.</p>
<p>Encapsulation in Java is achieved through access modifiers. We mark the fields as <code>private</code> and make them accessible via public setter and getter methods.</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Person</span> </span>{
    <span class="hljs-keyword">private</span> String name;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> age;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Person</span><span class="hljs-params">(String name, <span class="hljs-keyword">int</span> age)</span> </span>{
        <span class="hljs-keyword">this</span>.name = name;
        <span class="hljs-keyword">this</span>.age = age;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getName</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> name;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setName</span><span class="hljs-params">(String name)</span> </span>{
        <span class="hljs-keyword">this</span>.name = name;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getAge</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> age;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setAge</span><span class="hljs-params">(<span class="hljs-keyword">int</span> age)</span> </span>{
        <span class="hljs-keyword">this</span>.age = age;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">display</span><span class="hljs-params">()</span> </span>{
        System.out.println(<span class="hljs-string">"Name: "</span> + name + <span class="hljs-string">", Age: "</span> + age);
    }
}

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Main</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        Person person = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"Raj"</span>, <span class="hljs-number">30</span>);
        person.display(); <span class="hljs-comment">// Output - Name: Raj, Age: 30</span>

        person.setName(<span class="hljs-string">"Kumar"</span>);
        person.setAge(<span class="hljs-number">25</span>);
        person.display(); <span class="hljs-comment">// Output - Name: Kumar, Age: 25</span>
    }
}
</code></pre>
<p>In the above example, the fields and methods are encapsulated within a class named <code>Person</code>. </p>
<p>You declare the fields <code>name</code> and <code>age</code> as <code>private</code> and provide public setter and getter methods <code>getName()</code>, <code>setName()</code>, <code>getAge()</code>, and <code>setAge()</code> to modify the values as needed. </p>
<h2 id="heading-what-is-inheritance">What is Inheritance?</h2>
<p>Inheritance establishes a hierarchical relationship between two classes. </p>
<p>In this concept, one class inherits the fields (properties) and methods (behavior) of another class, while having properties and behavior of its own. </p>
<p>The class that inherits from another is called a subclass, derived class, or child class. The class from which the subclass inherits is known as the superclass, base class, or parent class. </p>
<p>In Java, inheritance is achieved using the <code>extends</code> keyword.</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">makeSomeNoise</span><span class="hljs-params">()</span></span>{
        System.out.println(<span class="hljs-string">"Make some animal noise"</span>);
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">makeSomeNoise</span><span class="hljs-params">()</span> </span>{
        System.out.println(<span class="hljs-string">"Bark"</span>);
    }
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doSomething</span><span class="hljs-params">()</span></span>{
        System.out.println(<span class="hljs-string">"Play with ball"</span>);
    }
}

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Main</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        Dog myDog = <span class="hljs-keyword">new</span> Dog();
        myDog.makeSomeNoise(); <span class="hljs-comment">// Output - Bark</span>
        myDog.doSomething(); <span class="hljs-comment">// Output - Play with ball</span>
    }
}
</code></pre>
<p>In the above example, the <code>extends</code> keyword indicates that the <code>Dog</code> class is the subclass of the <code>Animal</code> class. </p>
<p>The <code>Dog</code> class inherits the <code>makeSomeNoise()</code> method from the <code>Animal</code> class. This allows the <code>Dog</code> class to reuse the method and provide its own implementation without having to rewrite it completely. </p>
<p>You can also note that the <code>Dog</code> class has its own behavior through the <code>doSomething()</code> method. </p>
<p>Inheritance defines an "IS-A" relationship between the two classes. In our example, Dog IS-A Animal.</p>
<p>Note that Java supports multi-level inheritance. For example, <code>class Labrador</code> inherits from <code>class Dog</code>, which in turn inherits from <code>class Animal</code>. However, it does not support multiple inheritance. That is, a class is not allowed to inherit from two or more parent classes.</p>
<h2 id="heading-what-is-polymorphism">What is Polymorphism?</h2>
<p>Poly (many), morph (forms). </p>
<p>Polymorphism defines the capability of an object to be represented in different forms. </p>
<p>In Java, polymorphism can be categorized into two types: compile-time polymorphism and runtime polymorphism.</p>
<p>Compile-time polymorphism is achieved through method overloading – multiple methods have the same name but different type or number of parameters.</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MathOperation</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">add</span><span class="hljs-params">(<span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b)</span> </span>{
        <span class="hljs-keyword">return</span> a + b;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">add</span><span class="hljs-params">(<span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b, <span class="hljs-keyword">int</span> c)</span> </span>{
        <span class="hljs-keyword">return</span> a + b + c;
    }
}

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Main</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        MathOperation math = <span class="hljs-keyword">new</span> MathOperation();
        System.out.println(math.add(<span class="hljs-number">95</span>, <span class="hljs-number">5</span>));       <span class="hljs-comment">// Output - 100</span>
        System.out.println(math.add(<span class="hljs-number">75</span>, <span class="hljs-number">5</span>, <span class="hljs-number">20</span>));   <span class="hljs-comment">// Output - 100</span>
    }
}
</code></pre>
<p>In the above example, we have overloaded the <code>add()</code> method. There are two methods with the same name <code>add</code> but they have different number of parameters. </p>
<p>During compilation, based on the number of parameters passed to the method, the appropriate call is made.</p>
<p>Runtime polymorphism is achieved through method overriding – a subclass has a method with the same name and same set of parameters as that of its superclass method. However, it provides its own implementation of the method. </p>
<p>Here, the method resolution happens at runtime.</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">makeSomeNoise</span><span class="hljs-params">()</span> </span>{
        System.out.println(<span class="hljs-string">"Make some animal noise"</span>);
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">makeSomeNoise</span><span class="hljs-params">()</span> </span>{
        System.out.println(<span class="hljs-string">"Barks"</span>);
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Cat</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">makeSomeNoise</span><span class="hljs-params">()</span> </span>{
        System.out.println(<span class="hljs-string">"Meows"</span>);
    }
}

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Main</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        Animal myAnimal; 

        myAnimal = <span class="hljs-keyword">new</span> Dog(); 
        myAnimal.makeSomeNoise(); <span class="hljs-comment">// Output - Barks</span>

        myAnimal = <span class="hljs-keyword">new</span> Cat(); 
        myAnimal.makeSomeNoise(); <span class="hljs-comment">// Output - Meows</span>
    }
}
</code></pre>
<p>In the above example, the <code>makeSomeNoise()</code> method of the <code>Animal</code> class is overridden by the <code>Dog</code> and <code>Cat</code> subclasses and they provide their own implementation of this method. </p>
<p>During object creation, the <code>Animal</code> variable holds a <code>Dog</code> or <code>Cat</code> object and when the <code>makeSomeNoise()</code> method is called, the appropriate overridden method is called based on the actual object type.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, we explored the fundamental principles of Object-Oriented Programming (OOP). </p>
<p>Familiarity with these concepts is crucial for building robust, maintainable, and scalable software systems.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Object-Oriented Programming in C# – Explained With Examples ]]>
                </title>
                <description>
                    <![CDATA[ Welcome to this comprehensive guide on object-oriented programming (OOP) using C#. This article will delve into the four fundamental pillars of OOP: Inheritance Encapsulation Polymorphism Abstraction Whether you're a seasoned programmer or a beginn... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-oop-in-c-sharp/</link>
                <guid isPermaLink="false">66bb570129aa951a4c0628b9</guid>
                
                    <category>
                        <![CDATA[ C ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Object Oriented Programming ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Isaiah Clifford Opoku ]]>
                </dc:creator>
                <pubDate>Wed, 01 May 2024 12:14:44 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/04/Attractive-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Welcome to this comprehensive guide on object-oriented programming (OOP) using C#. This article will delve into the four fundamental pillars of OOP:</p>
<ul>
<li>Inheritance</li>
<li>Encapsulation</li>
<li>Polymorphism</li>
<li>Abstraction</li>
</ul>
<p>Whether you're a seasoned programmer or a beginner stepping into the world of C#, this article aims to enhance your understanding of OOP concepts and their implementation in C#. </p>
<p>If you're new to C#, consider taking the free certification course on <a target="_blank" href="https://www.freecodecamp.org/learn/foundational-c-sharp-with-microsoft/">freeCodeCamp</a> or the free course on <a target="_blank" href="https://learn.microsoft.com/en-us/courses/browse/?term=c%23&amp;resource_type=learning%20path">Microsoft Learn</a> to familiarize yourself with the language.</p>
<p>Remember, the principles of OOP are universal and apply to most object-oriented programming languages. Therefore, the knowledge you gain from this article can be applied to learning OOP in any language.</p>
<p>Let's get started!</p>
<h1 id="heading-table-of-contents">Table of Contents</h1>
<ol start="2">
<li><p><a class="post-section-overview" href="#heading-what-is-object-oriented-programming-oop">What is Object-Oriented Programming (OOP)</a></p>
</li>
<li><p><a class="post-section-overview" href="#why-use-object-oriented-programming">Why Use Object-Oriented Programming?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-four-pillars-of-object-oriented-programming">The Four Pillars of Object-Oriented Programming</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-inheritance">Inheritance</a></p>
</li>
<li><p><a class="post-section-overview" href="#types-of-inheritance">Types of Inheritance</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-encapsulation">Encapsulation</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-polymorphism">Polymorphism</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-abstraction">Abstraction</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-summary">Summary</a></p>
</li>
</ol>
<h1 id="what-is-object-oriented-programming-oop">What is Object-Oriented Programming (OOP)</h1>

<p>Object-Oriented Programming (OOP) is a programming paradigm that uses <code>objects</code> and <code>classes</code> to design and develop software applications. It is based on the concept of objects, which can contain data in the form of fields (attributes or properties) and code in the form of procedures (methods or functions).</p>
<p>Object-Oriented Programming offers several benefits, including:</p>
<ul>
<li><p><strong>Modularity</strong>: OOP promotes modularity by breaking down complex systems into smaller, manageable parts (objects). This makes it easier to maintain and update the code.</p>
</li>
<li><p><strong>Reusability</strong>: OOP allows you to reuse existing code by creating new objects based on existing ones. This saves time and effort in developing new applications.</p>
</li>
<li><p><strong>Flexibility</strong>: OOP provides flexibility in designing and implementing software systems. You can easily modify and extend the functionality of objects without affecting other parts of the system.</p>
</li>
<li><p><strong>Scalability</strong>: OOP supports scalability by allowing you to add new objects and classes as the system grows. This makes it easier to accommodate changes and enhancements in the software.</p>
</li>
</ul>
<p>As you can see, OOP offers several advantages that makes it a popular choice for developing software applications. Let's explore the four fundamental pillars of OOP in more detail.</p>
<h1 id="the-four-pillars-of-object-oriented-programming">The Four Pillars of Object-Oriented Programming</h1>

<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Add-a-heading.png" alt="Add-a-heading" width="600" height="400" loading="lazy"></p>
<p>The four pillars of Object-Oriented Programming are: </p>
<ol>
<li><strong>Inheritance</strong></li>
<li><strong>Encapsulation</strong></li>
<li><strong>Polymorphism</strong></li>
<li><strong>Abstraction</strong></li>
</ol>
<p>These pillars form the foundation of OOP and are essential concepts to understand when working with object-oriented programming languages like C#.</p>
<p>Let go deep into each of the pillars of OOP in the next sections.</p>
<p>Let's start with the first pillar of OOP: <code>Inheritance</code>.</p>
<h1 id="inheritance">Inheritance</h1>

<p>Inheritance is a concept used in most programming languages and is something you can't avoid when working with object-oriented programming. Programming languages like <code>C#</code> and Java are some of the languages that support inheritance. In this article, we will be looking at inheritance in <code>C#</code> and how to use it in your application.</p>
<h4 id="heading-what-is-inheritance">What is Inheritance?</h4>
<p>Imagine that you have a family tree, where each generation represents a class in C#. The first generation is the <code>base class</code>, which is the foundational class that provides the basic structure and properties. This could be likened to the patriarch of the family, who establishes the family's core values and characteristics.</p>
<p>As the family tree progresses, each subsequent generation inherits the traits and characteristics of the previous generation but also adds or modifies them to reflect their unique identity. These subsequent generations can be thought of as <code>derived</code> classes in C#, which inherit from the <code>base</code> class but also introduce their own unique features or modifications.</p>
<p>For example, the patriarch might have established the family's love for gardening, which becomes a fundamental trait passed down through the generations. However, as the family tree evolves, some members might develop a special interest in growing exotic plants, while others might focus on organic gardening. These special interests represent the unique characteristics of the derived classes, which inherit the basic love for gardening from the base class but also introduce their own unique features.</p>
<p>In this analogy, the <code>base</code> class is the patriarch, which represents the foundational class with its basic properties and characteristics. The <code>derived</code> classes are the subsequent generations, each with their unique features or modifications, inheriting the basic traits from the base class but also adding their own unique aspects. This process of inheritance allows for the creation of a rich and varied family tree, where each generation builds upon the previous one, introducing new traits and refining existing ones.</p>
<p>Inheritance is a mechanism that allows you to define a new <code>class</code> based on an existing <code>class</code>. The new class inherits all the members (fields, properties, and methods) of the existing class. The existing class is known as the <code>base</code> class, and the new class is known as the <code>derived</code> class.</p>
<p>Basic Syntax of inheritance in C#:</p>
<pre><code class="lang-csharp">
<span class="hljs-keyword">class</span> <span class="hljs-title">BaseClass</span>
{
    <span class="hljs-comment">// Base class members</span>
}

<span class="hljs-keyword">class</span> <span class="hljs-title">DerivedClass</span> : <span class="hljs-title">BaseClass</span>
{
    <span class="hljs-comment">// Derived class members</span>
}
</code></pre>
<p>In the above code snippet, <code>BaseClass</code> is the base class, and <code>DerivedClass</code> is the derived class. The <code>DerivedClass</code> inherits all the members of the <code>BaseClass</code>. The colon <code>(:)</code> is used to indicate that the <code>DerivedClass</code> is derived from the <code>BaseClass</code>.</p>
<p>If You are new to <code>C#</code> and you don't know what a class is, don't worry, I will explain it to you. A class is a blueprint for creating objects. It defines the properties and methods that an object of the class will have. Here is an example of a class in <code>C#</code>:</p>
<pre><code class="lang-csharp">
<span class="hljs-keyword">class</span> <span class="hljs-title">Person</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Name { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> Age { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Display</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">$"Name: <span class="hljs-subst">{Name}</span>, Age: <span class="hljs-subst">{Age}</span>"</span>);
    }
}
</code></pre>
<p>In the above code snippet, the <code>Person</code> class has two properties (<code>Name</code> and <code>Age</code>) and a method (<code>Display</code>). The properties represent the state of the object, and the method represents the behavior of the object. You can create an object of the <code>Person</code> class and set its properties like this:</p>
<pre><code class="lang-csharp">
Person person = <span class="hljs-keyword">new</span> Person();
person.Name = <span class="hljs-string">"John"</span>;
person.Age = <span class="hljs-number">30</span>;
</code></pre>
<p>You can call the <code>Display</code> method on the <code>person</code> object to display the name and age of the person:</p>
<pre><code class="lang-csharp">
person.Display(); <span class="hljs-comment">// Output: Name: John, Age: 30</span>
</code></pre>
<p>Before moving on with the article, let's look at some keywords you're going to come across  a lot <code>base class</code>, <code>Abstract class</code> ,<code>derived class</code>, <code>parent class</code>, and <code>child class</code>.</p>
<p>Let me explain them to you.</p>
<ul>
<li><strong>Base class</strong>: This is the class whose members are inherited by another class. It is also known as the parent class.</li>
</ul>
<pre><code class="lang-csharp">
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">BaseClass</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Display</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"This is a base class"</span>);
    }
}
</code></pre>
<ul>
<li><strong>Abstract class</strong>: This is a class that cannot be instantiated. It is used to provide a common base for all the derived classes. It can contain both abstract and non-abstract methods.</li>
</ul>
<pre><code class="lang-csharp">
<span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AbstractClass</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Display</span>(<span class="hljs-params"></span>)</span>;
}
</code></pre>
<ul>
<li><strong>Derived class</strong>: This is the class that inherits the members of the base class. It is also known as the child class.</li>
</ul>
<pre><code class="lang-csharp">
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">DerivedClass</span> : <span class="hljs-title">BaseClass</span>

{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Show</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"This is a derived class"</span>);
    }
}
</code></pre>
<p> So now you know what these keywords mean, let's move on to the next section.</p>
<h4 id="heading-types-of-inheritance">Types of Inheritance</h4>
<p>Inheritance can be classified into different types based on the way the classes are derived. The following are the types of inheritance: </p>
<ul>
<li><strong>Single Inheritance</strong>: Single inheritance is a fundamental concept in object-oriented programming where a class, known as the <code>derived class</code>, is based on another class, known as the <code>base class</code>. This is the simplest form of inheritance. </li>
</ul>
<p>To illustrate this, let's consider a real-world analogy. Imagine you are the only child of your father. In this scenario, you inherit characteristics from your father. This is akin to single inheritance in programming.</p>
<p>Let's look at an example in <code>C#</code>:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Father</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Display</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"This is the father class"</span>);
    }
}
</code></pre>
<p>In the above code, <code>Father</code> is the base class with a method <code>Display</code>.</p>
<p>Now, let's create a derived class <code>Child</code> that inherits from the <code>Father</code> class:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Child</span> : <span class="hljs-title">Father</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Show</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"This is the child class"</span>);
    }
}
</code></pre>
<p>In this code snippet, the <code>Child</code> class is derived from the <code>Father</code> class. The <code>Child</code> class inherits the <code>Display</code> method from the <code>Father</code> class. </p>
<p>You can create an object of the <code>Child</code> class and call the <code>Display</code> method. This demonstrates that the <code>Child</code> class can access the <code>Display</code> method from the <code>Father</code> class.</p>
<pre><code class="lang-csharp">Child child = <span class="hljs-keyword">new</span> Child();
child.Display(); <span class="hljs-comment">// Output: This is the father class</span>
</code></pre>
<ul>
<li><strong>Multilevel Inheritance</strong>: Multilevel inheritance is a concept in object-oriented programming where a class is derived from another derived class, creating a chain of inheritance.</li>
</ul>
<p>To better understand this, let's consider a family tree analogy. Assuming you are the <code>child</code> of your <code>father</code>, and your <code>father</code> is the <code>child</code> of your <code>grandfather</code>. In this scenario, you inherit characteristics from both your father and grandfather. This is similar to multilevel inheritance in programming.</p>
<p>Let's explore this concept with an example in <code>C#</code>:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Grandfather</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Display</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"This is the grandfather class"</span>);
    }
}
</code></pre>
<p>In the above code, <code>Grandfather</code> is the base class with a method <code>Display</code>.</p>
<p>Next, we created a derived class <code>Father</code> that inherits from the <code>Grandfather</code> class:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Father</span> : <span class="hljs-title">Grandfather</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Show</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"This is the father class"</span>);
    }
}
</code></pre>
<p>Here, the <code>Father</code> class is derived from the <code>Grandfather</code> class and inherits the <code>Display</code> method from it.</p>
<p>Finally, we created another derived class <code>Child</code> that inherits from the <code>Father</code> class:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Child</span> : <span class="hljs-title">Father</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DisplayChild</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"This is the child class"</span>);
    }
}
</code></pre>
<p>In this code snippet, the <code>Child</code> class is derived from the <code>Father</code> class. The <code>Child</code> class inherits the <code>Display</code> and <code>Show</code> methods from the <code>Father</code> class.</p>
<p>We can create an object of the <code>Child</code> class and call the <code>Display</code> and <code>Show</code> methods. This demonstrates that the <code>Child</code> class can access the <code>Display</code> and <code>Show</code> methods from the <code>Father</code> class.</p>
<pre><code class="lang-csharp">Child child = <span class="hljs-keyword">new</span> Child();
child.Display(); <span class="hljs-comment">// Output: This is the grandfather class</span>
child.Show(); <span class="hljs-comment">// Output: This is the father class</span>
child.DisplayChild(); <span class="hljs-comment">// Output: This is the child class</span>
</code></pre>
<ul>
<li><strong>Hierarchical Inheritance</strong>: Hierarchical inheritance is a concept in object-oriented programming where multiple classes are derived from a <code>single base class</code>, forming a <code>tree-like structure</code>.</li>
</ul>
<p>To illustrate this, let's consider a real-world analogy. Assuming you and your <code>siblings</code> share the <code>same parent</code>. In this scenario, all of you inherit characteristics from the same parent. This is akin to hierarchical inheritance in programming.</p>
<p>Let's explore this concept with an example in <code>C#</code>:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Parent</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Display</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"This is the parent class"</span>);
    }
}
</code></pre>
<p>In the above code, <code>Parent</code> is the base class with a method <code>Display</code>.</p>
<p> Next, we created two derived classes <code>Child1</code> and <code>Child2</code> that inherit from the <code>Parent</code> class:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Child1</span> : <span class="hljs-title">Parent</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Show1</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"This is the first child class"</span>);
    }
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Child2</span> : <span class="hljs-title">Parent</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Show2</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"This is the second child class"</span>);
    }
}
</code></pre>
<p>In this code snippet, the <code>Child1</code> and <code>Child2</code> classes are derived from the <code>Parent</code> class. Both classes inherit the <code>Display</code> method from the <code>Parent</code> class.</p>
<p>We can create objects of the <code>Child1</code> and <code>Child2</code> classes and call the <code>Display</code>, <code>Show1</code>, and <code>Show2</code> methods. This demonstrates that both <code>Child1</code> and <code>Child2</code> classes can access the <code>Display</code> method from the <code>Parent</code> class.</p>
<pre><code class="lang-csharp">Child1 child1 = <span class="hljs-keyword">new</span> Child1();
child1.Display(); <span class="hljs-comment">// Output: This is the parent class</span>
child1.Show1(); <span class="hljs-comment">// Output: This is the first child class</span>

Child2 child2 = <span class="hljs-keyword">new</span> Child2();
child2.Display(); <span class="hljs-comment">// Output: This is the parent class</span>
child2.Show2(); <span class="hljs-comment">// Output: This is the second child class</span>
</code></pre>
<p>Congratulation you have learned the basics of inheritance in C#, let's move to the next section <code>Encapsulation</code>.</p>
<h4 id="heading-understanding-encapsulation-and-properties-in-c">Understanding Encapsulation and Properties in C</h4>
<p>As we continue our journey through the pillars of OOP, we now arrive at <code>Encapsulation</code>. Before we delve into <code>Encapsulation</code>, it's crucial to understand a common concept in C# called <code>properties</code>.</p>
<p>Properties in C# are members of a class that provide a flexible mechanism to read, write, or compute the value of a private field. They can be used as if they are public data members, but they are actually special methods called accessors. These accessors are used to get and set the values of private fields.</p>
<p>If you're new to this concept, don't worry. Let's break it down with an example:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Person</span>
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span> name;

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Name
    {
        <span class="hljs-keyword">get</span> { <span class="hljs-keyword">return</span> name; }
        <span class="hljs-keyword">set</span> { name = <span class="hljs-keyword">value</span>; }
    }
}
</code></pre>
<p>In the above code snippet, the <code>Person</code> class has a private field <code>name</code> and a property <code>Name</code>. The property <code>Name</code> has two accessors: a <code>get</code> accessor to retrieve the value of the <code>name</code> field, and a <code>set</code> accessor to set the value of the <code>name</code> field.</p>
<p>Understanding properties is key to grasping the concept of <code>Encapsulation</code>, which we will explore in the next section. </p>
<h1 id="encapsulation">Encapsulation</h1>

<p>To understand <code>Encapsulation</code>, let's use an analogy. Consider a <code>gift box</code> that contains a <code>gift</code>. The <code>gift box</code> acts as a container that encapsulates the <code>gift</code>. The <code>gift</code> is hidden from the outside world and can only be accessed through the <code>gift box</code>. This is akin to <code>Encapsulation</code> in object-oriented programming.</p>
<p><code>Encapsulation</code> is the principle of bundling the data (fields) and methods (functions) that operate on the data into a single unit, known as a <code>class</code>. It restricts direct access to some of an object's components and allows access only through the methods of the class. In essence, <code>Encapsulation</code> conceals the internal state of an object and only exposes the necessary information to the outside world.</p>
<p>Let's see an example in C#:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Person</span>
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span> name;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> age;

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Name
    {
        <span class="hljs-keyword">get</span> { <span class="hljs-keyword">return</span> name; }
        <span class="hljs-keyword">set</span> { name = <span class="hljs-keyword">value</span>; }
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> Age
    {
        <span class="hljs-keyword">get</span> { <span class="hljs-keyword">return</span> age; }
        <span class="hljs-keyword">set</span> { age = <span class="hljs-keyword">value</span>; }
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Display</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">$"Name: <span class="hljs-subst">{Name}</span>, Age: <span class="hljs-subst">{Age}</span>"</span>);
    }
}
</code></pre>
<p>In the above code snippet, the <code>Person</code> class encapsulates the data (fields <code>name</code> and <code>age</code>) and methods (<code>Display</code>) into a single unit. The fields <code>name</code> and <code>age</code> are private, meaning they cannot be accessed directly from outside the class. The properties <code>Name</code> and <code>Age</code> provide controlled access to the private fields using <code>get</code> and <code>set</code> accessors.</p>
<p>Let's add another example to further illustrate this concept:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">BankAccount</span>
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">double</span> balance;

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> Balance
    {
        <span class="hljs-keyword">get</span> { <span class="hljs-keyword">return</span> balance; }
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">set</span> { balance = <span class="hljs-keyword">value</span>; }
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Deposit</span>(<span class="hljs-params"><span class="hljs-keyword">double</span> amount</span>)</span>
    {
        <span class="hljs-keyword">if</span> (amount &gt; <span class="hljs-number">0</span>)
        {
            Balance += amount;
        }
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Withdraw</span>(<span class="hljs-params"><span class="hljs-keyword">double</span> amount</span>)</span>
    {
        <span class="hljs-keyword">if</span> (amount &gt; <span class="hljs-number">0</span> &amp;&amp; Balance &gt;= amount)
        {
            Balance -= amount;
        }
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DisplayBalance</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">$"Balance: <span class="hljs-subst">{Balance}</span>"</span>);
    }
}
</code></pre>
<p>In this example, the <code>BankAccount</code> class encapsulates the <code>balance</code> field and the methods that operate on it (<code>Deposit</code>, <code>Withdraw</code>, <code>DisplayBalance</code>). The <code>balance</code> field is private and can only be accessed through the <code>Balance</code> property and the methods of the class. This ensures that the balance cannot be directly manipulated from outside the class, providing a secure way to manage a bank account.</p>
<p>Congratulations! You have learned about <code>Encapsulation</code> and how it is implemented in C#. Let's move on to the next section, <code>Polymorphism</code>.</p>
<h4 id="heading-understanding-polymorphism-in-c">Understanding Polymorphism in C</h4>
<p>As we delve deeper into the four pillars of OOP, we now encounter <code>Polymorphism</code>. The term <code>Polymorphism</code> originates from the Greek words <code>poly</code> (many) and <code>morphos</code> (forms), signifying "many forms". In the realm of object-oriented programming, <code>Polymorphism</code> denotes an object's ability to assume multiple forms.</p>
<p>To comprehend <code>Polymorphism</code>, let's consider a <code>music player</code>. It can play various types of music files, such as <code>MP3</code>, <code>WAV</code>, or <code>AAC</code>. Each of these file types is different, yet our music player can handle all of them. This is akin to <code>Polymorphism</code> in object-oriented programming.</p>
<h1 id="polymorphism">Polymorphism</h1>

<p><code>Polymorphism</code> is a core concept in object-oriented programming that allows objects of different classes to be treated as objects of a common superclass. It provides a single interface to represent multiple underlying forms (classes) and enables objects to be processed in a generic manner.</p>
<p>In C#, there are two types of <code>Polymorphism</code>:</p>
<ol>
<li><strong>Compile-time Polymorphism (Method Overloading)</strong></li>
<li><strong>Run-time Polymorphism (Method Overriding)</strong></li>
</ol>
<h3 id="heading-compile-time-polymorphism-method-overloading">Compile-time Polymorphism (Method Overloading)</h3>
<p><code>Compile-time Polymorphism</code>, also known as <code>Method Overloading</code>, allows a class to have multiple methods with the same name but different parameters. The compiler determines which method to invoke based on the number and types of arguments.</p>
<p>Here's an example of <code>Method Overloading</code> in C#:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Printer</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Print</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> message</span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">$"Printing string: <span class="hljs-subst">{message}</span>"</span>);
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Print</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> number</span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">$"Printing number: <span class="hljs-subst">{number}</span>"</span>);
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Print</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> message, <span class="hljs-keyword">int</span> copies</span>)</span>
    {
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; copies; i++)
        {
            Console.WriteLine(<span class="hljs-string">$"Printing string: <span class="hljs-subst">{message}</span>"</span>);
        }
    }
}
</code></pre>
<p>In this example, the <code>Printer</code> class has three <code>Print</code> methods with the same name but different parameters. This is an example of <code>Method Overloading</code> in C#.</p>
<h3 id="heading-run-time-polymorphism-method-overriding">Run-time Polymorphism (Method Overriding)</h3>
<p><code>Run-time Polymorphism</code>, also known as <code>Method Overriding</code>, allows a subclass to provide a specific implementation of a method that is already provided by its superclass.</p>
<p>Here's an example of <code>Method Overriding</code> in C#:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">MusicPlayer</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">virtual</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Play</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"Playing music"</span>);
    }
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Mp3Player</span> : <span class="hljs-title">MusicPlayer</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Play</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"Playing MP3 music"</span>);
    }
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">WavPlayer</span> : <span class="hljs-title">MusicPlayer</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Play</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"Playing WAV music"</span>);
    }
}
</code></pre>
<p>In this example, the <code>MusicPlayer</code> class has a virtual method <code>Play</code>. The <code>Mp3Player</code> and <code>WavPlayer</code> classes override the <code>Play</code> method with specific implementations for playing MP3 and WAV music, respectively. This is an example of <code>Method Overriding</code> in C#.</p>
<p>Let's see how <code>Polymorphism</code> can be used in a program:</p>
<pre><code class="lang-csharp">MusicPlayer player = <span class="hljs-keyword">new</span> Mp3Player();
player.Play(); <span class="hljs-comment">// Output: Playing MP3 music</span>

player = <span class="hljs-keyword">new</span> WavPlayer();
player.Play(); <span class="hljs-comment">// Output: Playing WAV music</span>
</code></pre>
<p>In this code snippet, we created an object of the <code>Mp3Player</code> class and assigned it to a variable of type <code>MusicPlayer</code>. We then called the <code>Play</code> method on the <code>player</code> object, which invokes the overridden <code>Play</code> method in the <code>Mp3Player</code> class. We then created an object of the <code>WavPlayer</code> class and assigned it to the <code>player</code> variable. When we call the <code>Play</code> method again, it invokes the overridden <code>Play</code> method in the <code>WavPlayer</code> class.</p>
<p>Congratulations! You have learned about <code>Polymorphism</code> and how it is implemented in C#. Let's move on to the final pillar of OOP, <code>Abstraction</code>.</p>
<h4 id="heading-understanding-abstraction-in-c">Understanding Abstraction in C</h4>
<p>As we delve into the final pillar of OOP, we encounter <code>Abstraction</code>. <code>Abstraction</code> is the process of hiding complex implementation details and exposing only the essential features of an object. It emphasizes on what an object does rather than how it does it.</p>
<p>To comprehend <code>Abstraction</code>, let's consider a <code>smartphone</code>. When you use a smartphone, you don't need to understand the intricacies of how the internal components like the <code>processor</code> or the <code>memory</code> work. You only need to know how to interact with the user interface to make calls, send messages, or use apps. This is akin to <code>Abstraction</code> in object-oriented programming.</p>
<h2 id="abstraction">Abstraction</h2>

<p><code>Abstraction</code> is a key concept in object-oriented programming that allows you to create a blueprint for a class with some abstract methods that must be implemented by the derived classes. It enables you to define the structure of a class without providing the implementation details.</p>
<p>In C#, <code>Abstraction</code> can be achieved using <code>abstract</code> classes and <code>interfaces</code>. Let's explore both concepts:</p>
<h3 id="heading-abstract-classes">Abstract Classes</h3>
<p>An <code>abstract class</code> is a class that cannot be instantiated and can contain both abstract and non-abstract methods. An abstract method is a method without a body that must be implemented by the derived classes.</p>
<p>Here's an example of an <code>abstract class</code> in C#:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Speak</span>(<span class="hljs-params"></span>)</span>;
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> : <span class="hljs-title">Animal</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Speak</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"The dog barks"</span>);
    }
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Cat</span> : <span class="hljs-title">Animal</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Speak</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"The cat meows"</span>);
    }
}
</code></pre>
<p>In this example, the <code>Animal</code> class is an abstract class with an abstract method <code>Speak</code>. The <code>Dog</code> and <code>Cat</code> classes inherit from the <code>Animal</code> class and provide specific implementations for the <code>Speak</code> method. This is an example of <code>Abstraction</code> using abstract classes in C#.</p>
<h3 id="heading-interfaces">Interfaces</h3>
<p>An <code>interface</code> is a reference type in C# that defines a contract for classes to implement. It contains only the declaration of the methods, properties, events, or indexers, without providing the implementation.</p>
<p>Here's an example of an <code>interface</code> in C#:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">IFlyable</span>
{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">Fly</span>(<span class="hljs-params"></span>)</span>;
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Bird</span> : <span class="hljs-title">IFlyable</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Fly</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"The bird flies"</span>);
    }
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Airplane</span> : <span class="hljs-title">IFlyable</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Fly</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"The airplane flies"</span>);
    }
}
</code></pre>
<p>In this example, the <code>IFlyable</code> interface defines a contract with a method <code>Fly</code>. The <code>Bird</code> and <code>Airplane</code> classes implement the <code>IFlyable</code> interface and provide specific implementations for the <code>Fly</code> method. This is an example of <code>Abstraction</code> using interfaces in C#.</p>
<p>Congratulations! You have now learned about <code>Abstraction</code> and how it is implemented in C#. The key takeaway is that <code>Abstraction</code> allows us to hide the complexity of the system and expose only the necessary details to the user.</p>
<h1 id="summary">Summary</h1>

<p>In this article, we have explored the four fundamental pillars of object-oriented programming (OOP) in C#: <code>Inheritance</code>, <code>Encapsulation</code>, <code>Polymorphism</code>, and <code>Abstraction</code>. </p>
<p>These pillars form the foundation of OOP and are essential concepts to understand when working with object-oriented programming languages like C#. The knowledge gained from this article will help you enhance your understanding of OOP concepts and their implementation in C#. </p>
<p>Thank you for reading this article, I hope you find it helpful. If you have any questions or feedback, feel free to reach out to me. Happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Object-Oriented Programming in Python – Explained With Examples ]]>
                </title>
                <description>
                    <![CDATA[ Object-oriented programming (OOP) is a style of programming that heavily relies on objects. These objects can have attributes and methods. While attributes store data, methods define behavior. Like many other programming languages, Python supports bo... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-oop-in-python/</link>
                <guid isPermaLink="false">66d45e0647a8245f78752a16</guid>
                
                    <category>
                        <![CDATA[ Object Oriented Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Damilola Oladele ]]>
                </dc:creator>
                <pubDate>Wed, 24 Apr 2024 14:39:28 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/04/WhatsApp-Image-2024-04-24-at-8.25.07-AM.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Object-oriented programming (OOP) is a style of programming that heavily relies on objects. These objects can have attributes and methods. While attributes store data, methods define behavior.</p>
<p>Like many other programming languages, Python supports both OOP and functional programming. However, OOP becomes valuable when writing large-sized and complex programs.</p>
<p>In this article, you will learn the benefits of OOP in Python, how to define a class, class and instance attributes, and instance methods. You will also learn the concept of encapsulation and how to implement inheritance between classes in Python.</p>
<p>To fully understand this article, you should have the following prerequisites:</p>
<ul>
<li><p>Basic knowledge of the Python programming language.</p>
</li>
<li><p>Familiarity with the concepts of functions and objects in programming.</p>
</li>
<li><p>Experience working with a code editor or integrated development environment (IDE).</p>
</li>
<li><p>Basic understanding of how to use a command-line terminal or console.</p>
</li>
</ul>
<p>Now let's dive in.</p>
<h2 id="heading-why-use-object-oriented-programming">Why Use Object-Oriented Programming?</h2>
<p>Object-oriented programming (OOP) offers several benefits when organizing and managing code. By grouping related data and functions into logical classes, OOP promotes code structure and simplifies maintenance, especially as programs grow in size and complexity. The <a target="_blank" href="https://en.wikipedia.org/wiki/Modular_programming">modular approach</a> makes it easier to understand, modify, and reuse code, thereby reducing development time.</p>
<p>Another benefit of OOP is its ability to provide a clear and relatable programming style, which can be more helpful for developers. The use of objects and the relationships between them mirror real-world concepts. This makes it easier to reason about code and design complex systems.</p>
<p>Finally, OOP's concepts such as encapsulation and inheritance, contribute to code robustness by promoting data protection and code reusability.</p>
<h2 id="heading-what-is-a-class-in-python">What is a Class in Python?</h2>
<p>OOP in Python heavily relies on the concept of <code>class</code>. You can think of a class as a blueprint that is used to create objects. To illustrate this, imagine that you have a blueprint for a speaker. You can use this blueprint to build multiple speakers. Each speaker that is created using the blueprint is an instance of the blueprint. Also, each created speaker has its attributes such as color, model, and name. They will also have their methods showing a certain kind of behavior such as volume up and volume down.</p>
<h2 id="heading-how-to-define-a-class-in-python">How to Define a Class in Python</h2>
<p>To define a class, you have to use the <code>class</code> keyword, provided by Python, then followed by the name of the class and a colon:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ClassName</span>:</span>
    <span class="hljs-keyword">pass</span>
</code></pre>
<p>Now using our earlier illustration, let’s create a class named <code>Speaker</code>. In your code editor, create a file named <code>classes.py</code> and copy the following lines of code into it:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Speaker</span>:</span>
    <span class="hljs-keyword">pass</span>

speaker_one = Speaker()
print(speaker_one)
</code></pre>
<p>In the preceding code, you defined a class named <code>Speaker</code> without any attributes or methods. You used the keyword <code>pass</code> in the class body. In Python, the <code>pass</code> keyword does nothing and is usually used as a placeholder.</p>
<p>In line four of the code, you created an instance of the <code>Speaker</code> class and assigned it to the variable <code>speaker_one</code>. This process is also known as instantiating an object from a class. You then printed <code>speaker_one</code> in line five.</p>
<p>Now run the code by running the command <code>python classes.py</code> in your terminal. You will get an output similar to this in your terminal:</p>
<pre><code class="lang-bash">&lt;__main__.Speaker object at 0x10087f8e0&gt;
</code></pre>
<p>The output shows that <code>speaker_one</code> is an object. <code>0x10087f8e0</code> in the output shows the memory address where Python stores the object on your computer.</p>
<p>The memory address in your terminal output will be different.</p>
<p>You can create several more instances from the <code>Speaker</code> class and they will all be different from one another. To verify this, let’s use the equality comparison (<strong>\==</strong>) operator. In your <code>classes.py</code> file, delete <code>print(speaker_one)</code> and add the following to the bottom of your code:</p>
<pre><code class="lang-python">speaker_two = Speaker()

<span class="hljs-keyword">if</span> speaker_one == speaker_two:
    print(<span class="hljs-string">"speaker one is the same as speaker two"</span>)
<span class="hljs-keyword">else</span>:
    print(<span class="hljs-string">"speaker one is different from speaker two"</span>)
</code></pre>
<p>Now run <code>python classes.py</code> in your terminal. You will get the following output:</p>
<pre><code class="lang-bash">speaker one is different from speaker two
</code></pre>
<h2 id="heading-class-and-instance-attributes">Class and Instance Attributes</h2>
<p>In this section, you'll add attributes to your <code>Speaker</code> class. You can see attributes as data stored within an object. While class attributes are common to all instances created from your class, instance attributes are unique to each instance.</p>
<p>Now modify your <code>classes.py</code> file by replacing your code with the following:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Speaker</span>:</span>
    brand = <span class="hljs-string">"Beatpill"</span> <span class="hljs-comment"># class attribute</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, color, model</span>):</span>
        self.color = color <span class="hljs-comment"># instance attribute</span>
        self.model = model <span class="hljs-comment"># instance attribute</span>
</code></pre>
<p>You should already be familiar with line one of your new code. In line two, you defined a class attribute, named <code>brand</code>, and assigned it the value <code>Beatpill</code>. Class attributes are variables that belong to the class itself, rather than to individual instances of the class. The effect of class attributes is that all instances you create from your class will inherit and share that class attribute and its value. In this case, every instance you create from your <code>Speaker</code> class will share the same <code>brand</code> value.</p>
<p>Line four of your code defines an <code>__init__</code> method, which takes in three parameters—<code>self</code>, <code>color</code>, and <code>model</code>. This method will be called anytime you create a new instance from your <code>Speaker</code> class. The <code>self</code> parameter is a reference to the <code>Speaker</code> class and it's a convention in Python to always have it as the first parameter in a <code>__init__</code> method. Line five and six set instance attributes, <code>color</code>, and <code>model</code> to your <code>Speaker</code> class.</p>
<p>So, every time you create a new instance from your class, you have to provide arguments for your <code>color</code> and <code>model</code> attributes. Not doing this will result in an error.</p>
<p>Now add the following to the bottom of your code:</p>
<pre><code class="lang-python">speaker_one = Speaker(<span class="hljs-string">"black"</span>, <span class="hljs-string">"85XB5"</span>)
speaker_two = Speaker(<span class="hljs-string">"red"</span>, <span class="hljs-string">"Y8F33"</span>)

print(<span class="hljs-string">f"speaker one is <span class="hljs-subst">{speaker_one.color}</span> while speaker two is <span class="hljs-subst">{speaker_two.color}</span>"</span>)
</code></pre>
<p>By adding the preceding code, you created two instances of the <code>Speaker</code> class—<code>speaker_one</code> and <code>speaker_two</code>. The arguments in each instance represent the values of their <code>color</code> and <code>model</code> attributes. You then printed a message that displays the color attribute of each object. Now, if you run the command <code>python classes.py</code> in your terminal, you will get the output:</p>
<pre><code class="lang-bash">speaker one is black <span class="hljs-keyword">while</span> speaker two is red
</code></pre>
<p>To see that both instances share the same <code>brand</code> class attribute, modify your <code>print()</code> function like this:</p>
<pre><code class="lang-python">print(
    <span class="hljs-string">f"speaker one is <span class="hljs-subst">{speaker_one.color}</span> while speaker two is <span class="hljs-subst">{speaker_two.color}</span>"</span>,
    speaker_one.brand,
    speaker_two.brand,
    sep=<span class="hljs-string">"\n"</span>,
)
</code></pre>
<p>Now run <code>python classes.py</code> and you will get the following output:</p>
<pre><code class="lang-bash">speaker one is black and speaker two is red
Beatpill
Beatpill
</code></pre>
<h2 id="heading-instance-methods">Instance Methods</h2>
<p>In addition to class and instance attributes, classes can also have methods, known as instance methods. Instance methods are functions defined within a class that operate on instances of the class. They use the class and instance attributes to provide behavior and functionality to the objects.</p>
<p>To add instance methods, modify your code file as follows:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Speaker</span>:</span>
    brand = <span class="hljs-string">"Beatpill"</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, color, model</span>):</span>
        self.color = color
        self.model = model

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">power_on</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">f"Powering on <span class="hljs-subst">{self.color}</span> <span class="hljs-subst">{self.model}</span> speaker."</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">power_off</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">f"Powering off <span class="hljs-subst">{self.color}</span> <span class="hljs-subst">{self.model}</span> speaker."</span>)


speaker_one = Speaker(<span class="hljs-string">"black"</span>, <span class="hljs-string">"85XB5"</span>)
speaker_two = Speaker(<span class="hljs-string">"red"</span>, <span class="hljs-string">"Y8F33"</span>)
</code></pre>
<p>In the example above, we've added two instance methods—<code>power_on()</code> and <code>power_off()</code>. These methods, just like the <code>__init__</code> method, take <code>self</code> as the first argument.</p>
<p>The <code>power_on()</code> method prints a message indicating that the speaker of the given color and model is being powered on. Similarly, the <code>power_off()</code> method prints a message about powering off the speaker.</p>
<p>To call these methods, add the following to the bottom of your file:</p>
<pre><code class="lang-python">speaker_one.power_on()
speaker_two.power_off()
</code></pre>
<p>Now run <code>python classes.py</code> in your terminal and you will get the following output:</p>
<pre><code class="lang-bash">Powering on black 85XB5 speaker.
Powering off red Y8F33 speaker.
</code></pre>
<h2 id="heading-encapsulation-in-python">Encapsulation in Python</h2>
<p>Encapsulation is one of the core concepts of OOP. It refers to the bundling of data (attributes) and methods within a class. Encapsulation provides data protection and control over how the code interacts with an object's internal state.</p>
<p>You can achieve encapsulation in Python by defining private attributes and methods within a class. By convention, private attributes and methods are prefixed with a single underscore (_). While Python does not have strict private modifiers like some other languages, the underscore prefix serves as a warning to other developers not to access or modify the attributes and methods directly from outside the class.</p>
<p>Here's an example of encapsulation in Python:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Speaker</span>:</span>
    brand = <span class="hljs-string">"Beatpill"</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, color, model</span>):</span>
        self._color = color  <span class="hljs-comment"># Private attribute</span>
        self._model = model  <span class="hljs-comment"># Private attribute</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">power_on</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">f"Powering on <span class="hljs-subst">{self._color}</span> <span class="hljs-subst">{self._model}</span> speaker."</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">power_off</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">f"Powering off <span class="hljs-subst">{self._color}</span> <span class="hljs-subst">{self._model}</span> speaker."</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_color</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> self._color

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">set_color</span>(<span class="hljs-params">self, new_color</span>):</span>
        self._color = new_color


speaker_one = Speaker(<span class="hljs-string">"black"</span>, <span class="hljs-string">"85XB5"</span>)
speaker_one.power_on()

<span class="hljs-comment"># Accessing a private attribute directly (not recommended)</span>
print(speaker_one._color)

<span class="hljs-comment"># Accessing a private attribute using the getter method (recommended)</span>
print(speaker_one.get_color())

<span class="hljs-comment"># Modifying a private attribute using the setter method (recommended)</span>
speaker_one.set_color(<span class="hljs-string">"white"</span>)
print(speaker_one.get_color())
</code></pre>
<p>In the preceding example, the <code>color</code> and <code>model</code> attributes are private attributes of the <code>Speaker</code> class. Although it is possible to access and modify these attributes directly from outside the class by using, for example, <code>print(speaker_one._color)</code>, this practice is discouraged. Doing so violates encapsulation and can lead to unintended behavior or data corruption.</p>
<p>Instead, the class provides getter <code>get_color()</code> and setter <code>set_color()</code> methods to access and modify the private attributes in a controlled manner. These methods act as an interface for interacting with the object's internal state, ensuring data integrity and enabling additional validation.</p>
<p>Encapsulation promotes code modularity, maintainability, and data protection by separating the internal state from the public interface (methods). It allows you to change the internal state without affecting the code that uses the class, as long as the public interface remains the same.</p>
<h2 id="heading-inheritance-in-python">Inheritance in Python</h2>
<p>Inheritance is another core concept of OOP. It allows classes to inherit attributes and methods from other classes. The new class inherits attributes and methods from the existing class, known as the parent or base class. The new class is called the child or derived class.</p>
<p>Inheritance promotes code reuse by allowing the child class to inherit and extend the functionality of the parent class. This helps in creating hierarchical relationships between classes and organizing code in a more structured and logical manner.</p>
<p>In Python, inheritance is implemented using the following syntax:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DerivedClass</span>(<span class="hljs-params">BaseClass</span>):</span>
    <span class="hljs-comment"># Derived class methods and attributes</span>
</code></pre>
<p>To see how inheritance works, modify your code as follows:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Speaker</span>:</span>
    brand = <span class="hljs-string">"Beatpill"</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, color, model</span>):</span>
        self._color = color
        self._model = model

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">power_on</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">f"Powering on <span class="hljs-subst">{self._color}</span> <span class="hljs-subst">{self._model}</span> speaker."</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">power_off</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">f"Powering off <span class="hljs-subst">{self._color}</span> <span class="hljs-subst">{self._model}</span> speaker."</span>)

<span class="hljs-comment"># Add a SmartSpeaker class and make it inherit from the Speaker class</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SmartSpeaker</span>(<span class="hljs-params">Speaker</span>):</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, color, model, voice_assistant</span>):</span>
        super().__init__(color, model)
        self._voice_assistant = voice_assistant

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">say_hello</span>(<span class="hljs-params">self</span>):</span>
        print(<span class="hljs-string">f"Hello, I am <span class="hljs-subst">{self._voice_assistant}</span>"</span>)


<span class="hljs-comment"># Create an instance of the SmartSpeaker class</span>
smart_speaker = SmartSpeaker(<span class="hljs-string">"black"</span>, <span class="hljs-string">"XYZ123"</span>, <span class="hljs-string">"Alexa"</span>)
smart_speaker.power_on()  <span class="hljs-comment"># Inherited from Speaker</span>
smart_speaker.say_hello()
</code></pre>
<p>In the preceding code, the <code>SmartSpeaker</code> class is derived from the <code>Speaker</code> class. The <code>SmartSpeaker</code> class inherits the attributes and methods of the <code>Speaker</code> class.</p>
<p>The <code>__init__</code> method of the <code>SmartSpeaker</code> class calls the <code>__init__</code> method of the <code>Speaker</code> class using <code>super().__init__(color, model)</code>. This ensures that the inherited <code>_color</code> and <code>_model</code> attributes are properly initialized. Also, the <code>SmartSpeaker</code> class has its own attribute <code>_voice_assistant</code>, and a new method <code>say_hello</code>.</p>
<p>Now run <code>python classes.py</code> in your terminal and you will get the following output:</p>
<pre><code class="lang-bash">Powering on black XYZ123 speaker.
Hello, I am Alexa
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Throughout this article, we highlighted the benefits of Object-Oriented Programming (OOP) and demonstrated how to define classes, create and use instance attributes and methods. We provided practical examples to illustrate the implementation of classes in Python, as well as key OOP concepts such as encapsulation and inheritance.</p>
<p>Applying the lessons covered in this article will help you improve your Python programming experience and increase the efficiency and maintainability of your code.</p>
<h2 id="heading-references-and-further-reading">References and Further Reading</h2>
<ul>
<li><p>https://en.wikipedia.org/wiki/Object-oriented_programming</p>
</li>
<li><p>https://realpython.com/python3-object-oriented-programming/</p>
</li>
<li><p>https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object-oriented_programming</p>
</li>
<li><p>https://docs.python.org/3/tutorial/classes.html</p>
</li>
<li><p>https://realpython.com/python-classes/</p>
</li>
<li><p>https://realpython.com/python-double-underscore/</p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build an Online Banking System – Python Object-Oriented Programming Tutorial ]]>
                </title>
                <description>
                    <![CDATA[ By Jacob Isah  Object-Oriented Programming (OOP) is a fundamental concept in software engineering that allows software engineers to structure code in a more organized and modular way.  Python, with its clear and concise syntax, is an excellent langua... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-an-online-banking-system-python-oop-tutorial/</link>
                <guid isPermaLink="false">66d45f359208fb118cc6cfc7</guid>
                
                    <category>
                        <![CDATA[ Object Oriented Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 20 Mar 2024 18:17:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/03/OOP_in_Python.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Jacob Isah </p>
<p>Object-Oriented Programming (OOP) is a fundamental concept in software engineering that allows software engineers to structure code in a more organized and modular way. </p>
<p>Python, with its clear and concise syntax, is an excellent language for learning and implementing OOP principles. </p>
<p>In this article, we'll  look at the basics of OOP in Python by building a simple online banking system.</p>
<h2 id="heading-an-overview-of-oop-concepts">An Overview of OOP Concepts</h2>
<p>Before we start coding, let's understand the key concepts of OOP:</p>
<ul>
<li><strong>Classes</strong>: Classes are blueprints for creating objects. They define the attributes (data) and methods (functions) that objects of that class will have.</li>
<li><strong>Objects</strong>: Objects are instances of classes. They represent real-world entities and encapsulate data and behavior.</li>
<li><strong>Inheritance</strong>: Inheritance allows a class (subclass) to inherit attributes and methods from another class (superclass). It promotes code reuse and supports hierarchical relationships between classes.</li>
<li><strong>Constructor:</strong> A constructor ( <code>__init__()</code> ) is a special type of method that is automatically called when an object of a class is created. Its primary purpose is to initialize the newly created object, setting initial values for its attributes or performing any necessary setup tasks.</li>
</ul>
<h2 id="heading-how-to-build-an-online-banking-system">How to Build An Online Banking System</h2>
<p>Let's start by creating the basic structure for our online banking system using OOP principles.</p>
<h3 id="heading-how-to-create-a-class-and-constructor">How to Create A Class and Constructor</h3>
<p>Let's create a class and initiate the class with the constructor:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Account</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, name, account_number, balance</span>):</span>
        self.name = name
        self.account_number = account_number
        self.balance = balance
</code></pre>
<p>In the example above:</p>
<ul>
<li>The <code>class</code> keyword declares an <code>Account</code> class.</li>
<li>The <code>__init__()</code> method is the constructor, defined with the special double underscore notation at the beginning and end.</li>
<li><code>self</code> is a reference to the instance of the class. It is the first parameter of all instance methods in Python.</li>
<li><code>name</code> is the name of the account holder.</li>
<li><code>account_number</code>  is a unique identifier for the savings account, and <code>balance</code> are parameters passed to the constructor.</li>
<li>Inside the constructor <code>self.name</code>, <code>self.account_number</code>, and <code>self.balance</code> are attributes of the class <code>Account</code> that are initialized with the values of <code>name</code>, <code>account_number</code> and <code>balance</code>, respectively.</li>
</ul>
<p>Constructors can perform various tasks such as initializing attributes, opening connections, loading data, and more. They are essential for ensuring that objects are properly set up and ready for use as soon as they are created.</p>
<h3 id="heading-how-to-create-methods-functions">How to Create Methods (functions)</h3>
<p>The next thing to do is to write the different methods for our <code>Account</code> class. Users should be able to deposit and withdraw.</p>
<h4 id="heading-how-to-create-a-deposit-method">How to create a deposit method</h4>
<pre><code class="lang-python">    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">deposit</span>(<span class="hljs-params">self, amount</span>):</span>
        self.balance += amount
        print(<span class="hljs-string">f"<span class="hljs-subst">{self.name}</span> Deposited <span class="hljs-subst">{amount}</span> $. Current balance is: <span class="hljs-subst">{self.balance}</span>"</span>)
</code></pre>
<p>In the example above:</p>
<ul>
<li>The <code>deposit</code> method allows users to add funds to their account.</li>
<li>The method takes an additional parameter <code>amount</code>, which is the amount to be deposited.</li>
<li>Inside the method, the <code>amount</code> is added to the current balance using <code>self.balance += amount</code>.</li>
<li>A message is printed showing the depositor name and the amount deposited and the balance is updated.</li>
</ul>
<h4 id="heading-how-to-create-a-withdraw-method">How to create a withdraw method</h4>
<pre><code class="lang-python">    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">withdraw</span>(<span class="hljs-params">self, amount</span>):</span>
        <span class="hljs-keyword">if</span> self.balance &gt;= amount:
            self.balance -= amount
            print(<span class="hljs-string">f"<span class="hljs-subst">{self.name}</span> Withdrew <span class="hljs-subst">{amount}</span> $. Current balance is: <span class="hljs-subst">{self.balance}</span>"</span>)
        <span class="hljs-keyword">else</span>:
            print(<span class="hljs-string">"You don't have enough funds to withdraw."</span>)
</code></pre>
<p>In the example above:</p>
<ul>
<li>The <code>withdraw</code> method allows users to withdraw funds from their account.</li>
<li>The method also takes an <code>amount</code> parameter which is the amount our user wants to withdraw.</li>
<li>The method checks if the account balance (<code>self.balance</code>) is greater than or equal to the amount our user wants to withdraw.</li>
<li>If the balance is enough, the withdrawal amount is removed from the balance using <code>self.balance -= amount</code>.</li>
<li>If the balance is not enough, a message stating “You don't have enough funds to withdraw.” is printed to the user.</li>
</ul>
<h3 id="heading-how-inheritance-works">How Inheritance Works</h3>
<p>Having explained inheritance above, let's see how it works in code. We are going to create a class that inherits the <code>Account</code> class. </p>
<p>Note that the <code>Account</code> class is the supper class, while the <code>Savings_Account</code> class is a subclass, also known as a child class.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Savings_Account</span>(<span class="hljs-params">Account</span>):</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, name, account_number, balance, interest_rate</span>):</span>
        super().__init__(name, account_number, balance)
        self.interest_rate = interest_rate
</code></pre>
<p>In the above code:</p>
<ul>
<li>The <code>__init__</code> method is the constructor for the <code>Savings_Account</code> class.</li>
<li>It accepts four parameters: <code>name</code> which is the name of the account holder,  <code>account_number</code>, which is a unique identifier for the savings account, <code>balance</code>, which is the initial balance of the account, and <code>interest_rate</code>, which is the annual interest rate (expressed as a decimal) for the account.</li>
<li>The <code>super().__init__(name, account_number, balance)</code> line calls the constructor of the parent class (<code>Account</code>) to initialize the account number and balance.</li>
<li>The <code>self.interest_rate = interest_rate</code> line sets the interest rate specific to the savings account. it is not inherited</li>
</ul>
<h3 id="heading-how-to-create-an-addinterest-method">How to Create An <code>add_interest</code>  Method</h3>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add_interest</span>(<span class="hljs-params">self</span>):</span>
    interest = self.balance * self.interest_rate
    self.deposit(interest)
</code></pre>
<p>In the example above:</p>
<ul>
<li>The <code>add_interest</code> method calculates and adds interest to the account balance.</li>
<li>The method calculates the interest by multiplying the current balance (<code>self.balance</code>) with the interest rate (<code>self.interest_rate</code>).</li>
<li>The result is stored in the <code>interest</code> variable.</li>
<li>Finally, the <code>self.deposit(interest)</code> line calls the <code>deposit</code> method (defined in the parent <code>Account</code> class) to add the interest amount to the account balance.</li>
</ul>
<h3 id="heading-how-to-create-and-use-objects">How to Create and Use Objects</h3>
<p>Your class is just a template. You need to create an object for your class to work.</p>
<p>Now, let's create objects from our classes and interact with them.</p>
<pre><code class="lang-python">account1 = Account(<span class="hljs-string">"John Doe"</span>, <span class="hljs-string">"123456"</span>, <span class="hljs-number">1000</span>)
account1.deposit(<span class="hljs-number">500</span>)
account1.withdraw(<span class="hljs-number">200</span>)
print()

savings_account = Savings_Account(<span class="hljs-string">"John Doe"</span>, <span class="hljs-string">"789012"</span>, <span class="hljs-number">2000</span>, <span class="hljs-number">0.05</span>)
savings_account.deposit(<span class="hljs-number">1000</span>)
savings_account.add_interest()
savings_account.withdraw(<span class="hljs-number">500</span>)
savings_account.withdraw(<span class="hljs-number">1000</span>)
</code></pre>
<p>In the above code:</p>
<ul>
<li>We created an instance <code>account1</code> of the <code>Account</code> class and performed deposit and withdrawal operations.</li>
<li>Similarly, we created an instance <code>savings_account</code> of the <code>Savings_Account</code> class and demonstrated deposit, interest addition, and withdrawal operations.</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Object-Oriented Programming is a powerful paradigm that allows software engineers to write code that is reusable, maintainable, and can scale. </p>
<p>Python's simplicity makes it an excellent choice for learning and implementing OOP concepts. </p>
<p>By building a simple online banking system, I've show you the basic concepts of classes, objects, and inheritance in Python. </p>
<p>Happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
