<?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[ Lucas - 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[ Lucas - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 24 May 2026 16:29:48 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/lucasgarcez/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <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 Create a React Native Splash Screen ]]>
                </title>
                <description>
                    <![CDATA[ In this article, you'll get a hands-on practical guide for creating a native splash screen for React Native CLI applications.  Note that this tutorial is not applicable for apps created with Expo. SVG Icon Image and Background The first thing you nee... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/react-native-splash-screen/</link>
                <guid isPermaLink="false">66ba2d7cde9370f66eeb0a95</guid>
                
                    <category>
                        <![CDATA[ React Native ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Lucas ]]>
                </dc:creator>
                <pubDate>Wed, 08 May 2024 19:17:54 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/05/article-1-rnsplash-2.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, you'll get a hands-on practical guide for creating a native splash screen for React Native CLI applications. </p>
<p>Note that this tutorial is not applicable for apps created with Expo.</p>
<h2 id="heading-svg-icon-image-and-background">SVG Icon Image and Background</h2>
<p>The first thing you need is an image. It can be in any format, but I recommend using SVG because, from it, you will generate icons of various sizes for different types of Android and iOS devices.</p>
<p>You will also need a background color that complements or contrasts your project's primary color. In my case, I will use #074C4E.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/nubble-logo.png" alt="Image" width="600" height="400" loading="lazy">
<em>icon imagem and backgorund color</em></p>
<h2 id="heading-add-the-image-to-the-project">Add the Image to the Project</h2>
<p>Next, add the SVG image to your project. It doesn't matter where. The most important thing is remembering the path because you will need to reference it later. </p>
<p>In my case, I placed it in <code>src/assets/svgs/logo-vertical-white.svg</code>.</p>
<h2 id="heading-how-to-use-the-react-native-bootsplash-library">How to Use the react-native-bootsplash Library</h2>
<p>You will use the <code>[react-native-bootsplash](https://github.com/zoontek/react-native-bootsplash)</code>  library to create native splash screens. This library will help you in three essential areas to guarantee your users an excellent experience when encountering the splash screen.</p>
<ol>
<li><strong>Native Splash Screens</strong>: React Native apps have a "JavaScript side" that only loads after the native side is ready. Therefore, to present a splash screen quickly, a native experience is necessary. The good news is that all the code is already inside the library, so you just need to connect it to your project.</li>
<li><strong>Generation of Images and Files</strong>: When creating native splash screens, it is necessary to create specific image files for each platform. This can be done through tools like Xcode and Android Studio. Fortunately, the library comes with a CLI (command-line interface) that allows you to generate these files with just one command!</li>
<li><strong>Hide at the Right Moment</strong>: In many cases, even after the native side has loaded, the app may still not be ready to display content to the user. On the JavaScript side, you still need to load your navigation stack, fetch the user's authentication status, or call the API to fetch some data. With the <code>react-native-bootsplash</code>, you can choose when to hide the splash screen.</li>
</ol>
<p>First, let's add the library. As I am using Yarn as my dependency manager, I will execute the command:</p>
<pre><code class="lang-bash">yarn add react-native-bootsplash
</code></pre>
<p>Since the library has native dependencies, you need to install the pods on the iOS side. Inside the <code>ios</code> folder, run the following command:</p>
<pre><code class="lang-bash">pod install
</code></pre>
<p>Great, the library installation is complete 😁. In case you're wondering, the native Android dependencies are automatically installed when you run the <code>yarn android</code> command. We'll do this later after finishing the setup.</p>
<h2 id="heading-how-to-generate-the-splash-screen-files">How to Generate the Splash Screen Files</h2>
<p>In addition to installing the library, you need to generate the files and images mentioned earlier and update a few native files after that.</p>
<p>The <code>react-native-bootsplash</code> has a command that helps us create all the necessary native files and images to create a native Android and iOS splash screen.</p>
<p>It's worth mentioning that the library also has a premium option, where you can buy a license key to unlock extra CLI commands, like adding more than one icon on the screen and generating different images for Dark Mode. You will use the simplest splash screen, so you don't need a license key. But I highly recommend it if you have any of the use cases mentioned above and also to support the library's author, who does an incredible job.</p>
<p>To generate the files, you'll need the following to run the command, which you should customize according to your project:</p>
<ol>
<li>File path and name: <code>src/assets/svgs/logo-vertica-white.svg</code></li>
<li>The background color: <code>074C4E</code></li>
<li>The logo width: <code>105</code></li>
</ol>
<pre><code class="lang-bash">yarn react-native generate-bootsplash src/assets/svgs/logo-vertica-white.svg \\
   --platforms=android,ios \\
   --background=074C4E \\
   --logo-width=105
</code></pre>
<p>After running this command, you will see that the native image files, color, and storyboard have been successfully generated.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/terminal.png" alt="Image" width="600" height="400" loading="lazy">
<em>terminal output</em></p>
<h2 id="heading-how-to-connect-the-library-to-the-project">How to Connect the Library to the Project</h2>
<p>It is time to integrate the library and newly created splash screen with the project by modifying some native files.</p>
<h3 id="heading-ios-appdelegatemm">iOS - AppDelegate.mm</h3>
<p>On iOS, the file where you configure libraries with native dependencies is the <strong>AppDelegate.mm</strong>. </p>
<p>And you will do this in two steps. First, import the library at the top of the file:</p>
<pre><code class="lang-cpp"><span class="hljs-meta">#import <span class="hljs-meta-string">"RNBootSplash.h"</span></span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/ios-import.png" alt="Image" width="600" height="400" loading="lazy">
<em>importing BootSplash on AppDelegate</em></p>
<p>The second change in this file is to add the function that will connect the native and JavaScript sides. Add this snippet at the end of the project before the last <code>@end</code>. The code will be different if you use a react-native version below 0.74.</p>
<pre><code class="lang-cpp"><span class="hljs-comment">// ⬇️ Add this before file @end (for react-native 0.74+)</span>
- (<span class="hljs-keyword">void</span>)customizeRootView:(RCTRootView *)rootView {
  [RNBootSplash initWithStoryboard:@<span class="hljs-string">"BootSplash"</span> rootView:rootView]; <span class="hljs-comment">// ⬅️ initialize the splash screen</span>
}

<span class="hljs-comment">// OR</span>

<span class="hljs-comment">// ⬇️ Add this before file @end (for react-native &lt; 0.74)</span>
- (UIView *)createRootViewWithBridge:(RCTBridge *)bridge
                          moduleName:(NSString *)moduleName
                           initProps:(NSDictionary *)initProps {
  UIView *rootView = [super createRootViewWithBridge:bridge moduleName:moduleName initProps:initProps];
  [RNBootSplash initWithStoryboard:@<span class="hljs-string">"BootSplash"</span> rootView:rootView]; <span class="hljs-comment">// ⬅️ initialize the splash screen</span>
  <span class="hljs-keyword">return</span> rootView;
}
</code></pre>
<p>In my case, I am on react-native 0.73, so my modification looks like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/ios-code.png" alt="Image" width="600" height="400" loading="lazy">
<em>added createRootViewWithBridge (react-native &lt; 0.74)</em></p>
<h3 id="heading-android-stylesxml">Android - styles.xml</h3>
<p>On Android, you need to change three native files. Let's start with <strong>styles.xml</strong>.</p>
<p>Inside the <strong>android/app/src/main/res/values/styles.xml</strong> file, add the following code snippet inside the <code>resources</code> tag. Remember, there is already a <code>style</code> tag within it – do not replace it. Add an extra one.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">style</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"BootTheme"</span> <span class="hljs-attr">parent</span>=<span class="hljs-string">"Theme.BootSplash"</span>&gt;</span><span class="xml">
    <span class="hljs-tag">&lt;<span class="hljs-name">item</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"bootSplashBackground"</span>&gt;</span>@color/bootsplash_background<span class="hljs-tag">&lt;/<span class="hljs-name">item</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">item</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"bootSplashLogo"</span>&gt;</span>@drawable/bootsplash_logo<span class="hljs-tag">&lt;/<span class="hljs-name">item</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">item</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"postBootSplashTheme"</span>&gt;</span>@style/AppTheme<span class="hljs-tag">&lt;/<span class="hljs-name">item</span>&gt;</span>
</span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/android-styles.png" alt="Image" width="600" height="400" loading="lazy">
<em>styles.xml</em></p>
<h3 id="heading-android-androidmanifestxml">Android - AndroidManifest.xml</h3>
<p>To connect the splash screen in the file <strong>android/app/src/main/AndroidManifest.xml</strong>, you have to add the property <code>android:theme="@style/BootTheme"</code> inside the <code>activity</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/android-AndroidManifest.png" alt="Image" width="600" height="400" loading="lazy">
<em>My AndroidManifest.xml</em></p>
<h3 id="heading-android-modify-the-mainactivityjavakt">Android - Modify the MainActivity.java/kt</h3>
<p>You need to initiate the splash screen within the <code>MainActivity</code>. Depending on your version of React Native, your file may have a Java or Kotlin extension. You have to modify or create the <code>onCreate</code> method if it does not exist.</p>
<p>I literally copied the code below from the library <strong>README</strong> file, so you don't need to jump there but feel free to check it <a target="_blank" href="https://github.com/zoontek/react-native-bootsplash?tab=readme-ov-file#android-1">here</a>.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Java (react-native &lt; 0.73)</span>
<span class="hljs-comment">// …</span>

<span class="hljs-comment">// add these required imports:</span>
<span class="hljs-keyword">import</span> android.os.Bundle;
<span class="hljs-keyword">import</span> com.zoontek.rnbootsplash.RNBootSplash;

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MainActivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ReactActivity</span> </span>{

  <span class="hljs-comment">// …</span>

  <span class="hljs-meta">@Override</span>
  <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span><span class="hljs-params">(Bundle savedInstanceState)</span> </span>{
    RNBootSplash.init(<span class="hljs-keyword">this</span>, R.style.BootTheme); <span class="hljs-comment">// ⬅️ initialize the splash screen</span>
    <span class="hljs-keyword">super</span>.onCreate(savedInstanceState); <span class="hljs-comment">// super.onCreate(null) with react-native-screens</span>
  }
}
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/android-MainActivity.png" alt="Image" width="600" height="400" loading="lazy">
<em>My final MainActivity.java</em></p>
<h3 id="heading-hide-the-splash-screen">Hide the Splash Screen</h3>
<p>The implementation is ready for both platforms! But before running the app, you must hide the splash screen at some point on the JavaScript side; otherwise, the app will open and get stuck.</p>
<p>Of course, where to put it depends significantly on what you need to load for your app to be ready to display to the user. A classic example is waiting for React Navigation to load the navigation stack, which is signaled through the <code>onReady</code> callback.</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> BootSplash <span class="hljs-keyword">from</span> <span class="hljs-string">'react-native-bootsplash'</span>;
<span class="hljs-comment">// ...</span>

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Router</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// ...</span>
    <span class="hljs-keyword">return</span> (
    &lt;NavigationContainer onReady={<span class="hljs-function">() =&gt;</span> BootSplash.hide({fade: <span class="hljs-literal">true</span>})}&gt;
      {Stack}
    &lt;/NavigationContainer&gt;
  );
}
</code></pre>
<h3 id="heading-you-are-ready-to-go">You are ready to go!</h3>
<p>Your splash screen is ready for use! However, since you modified native files, rebuilding the app is necessary. To do this, run the commands <code>yarn ios</code> and <code>yarn android</code> to see how your implementation works.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/showcase.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Thanks for reading! If you speak Portuguese and would like more content about React Native, subscribe to my YouTube channel <a target="_blank" href="https://www.youtube.com/@Coffstack">here</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
