---
description: Programming Paradigm
---

# Object Oriented Programming

## Object

**Objects** can be considered as real-world instances of entities like class, that have some characteristics and behaviors.

## Class

A blueprint or template for creating similar types of objects. They usually have:

* Attributes or Data
* Behaviors or Methods

#### Class Relationships

{% tabs %}
{% tab title="Inheritance" %}
* _**"is-a"**_ relationship

<pre class="language-csharp"><code class="lang-csharp"><strong>class Animal            // parent class
</strong>{
    public virtual void Move() {
        Console.WriteLine("i can move");
    }
}
<strong>class Dog : Animal    // child class    inheritance
</strong>{
    public override void Move() {
        Console.WriteLine("i can run");
    }
}
</code></pre>
{% endtab %}

{% tab title="Association->Aggregation->Composition" %}
* _**"has-a"**_ relationship : can be one-to-many, many-to-one, many-to-many.
* classes exist independently

<pre class="language-csharp"><code class="lang-csharp"><strong>class Customer
</strong>{
    public string Name { get; set; }
<strong>    public void PlaceOrder(Order order)    // association
</strong>    {
        Console.WriteLine("Order Placed");
    }
}
<strong>class Order
</strong>{
<strong>    public Customer Customer { get; set; }    // association
</strong>}
</code></pre>

#### Aggregation

* child class can exist independently of the parent class

```csharp
class OrderItem        // child class
{
    public string Name { get; set; }
    public int Quantity { get; set; }
}
class Order            // parent class
{
    private List<OrderItem> items = new List<OrderItems>();    // aggregation
    public void AddItem(OrderItem item)
    {
        items.Add(item);
    }   
}
```

#### Composition

* child class cannot exist independently of the parent class

```csharp
class Engine     // child class
{
    public void Start() {
        Console.WriteLine("Engine Started");
    }
}
class Car         // parent class
{
    private Engine engine = new Engine();    // composition
    public void Start() {
        engine.Start();
    }
}
```
{% endtab %}
{% endtabs %}

## Inheritance

A mechanism in which one class inherits the properties of another class.

* Single Inheritance&#x20;
* Multilevel Inheritance
* Multiple Inheritance (Not Supported in C# due to [The Diamond Problem](https://en.wikipedia.org/wiki/Multiple_inheritance))
* Hierarchical Inheritance
* Hybrid Inheritance

{% tabs %}
{% tab title="C#" %}
```csharp
class Parent { ... }  

class Child1 : Parent { ... }    // Single, Hierarchical

class Child2 : Parent { ... }    // Hierarchical, Multilevel

class GrandChild : Child2 { ... }    //Muiltilevel

interface Service1 { ... }
interface Service2 { ... }
class Child : Service1, Service2 { ... }    // Multiple
```
{% endtab %}

{% tab title="Python" %}
```python
class Parent:

class Child1(Parent):    # Single, Hierarchical

class Child2(Parent):    # Hierarchical, Multilevel

class GrandChild(Child2):    # Multilevel

class Parent1:

class Parent2:

class Child(Parent1, Parent2):    # Multiple
```
{% endtab %}
{% endtabs %}

## Polymorphism

A concept where an object behaves differently in different situations.

#### Compile-time Polymorphism / Static Dispatch

* Function/Method/Operator Overloading a.k.a. Early Binding

> With overloading you have a function with different sets of parameters. The function that is to be executed is determined using the number and type of the parameters you provide. As these are known at compile time, the compiler already determines the function to use. Because of this, it is called compile time polymorphism.

<pre class="language-csharp"><code class="lang-csharp">public class Calculate {  
<strong>    public int Add(int a, int b) {
</strong>        return a + b;
    }
<strong>    public int Add(int a, int b, int c) {    // Function Overloading
</strong>        return a + b + c;
    }
}  
</code></pre>

#### Runtime Polymorphism / Dynamic Dispatch

* Method Overriding (`virtual`/`abstract`) a.k.a. Late Binding

> When you are overriding a virtual function of a base class in one or more derived classes and then call this function from a base class, the actual class of the underlying object is not clear at compile time. Thus it is determined only at runtime which function is executed. That is why it is called runtime polymorphism.

<pre class="language-csharp"><code class="lang-csharp">public class Drawing {  
<strong>    public virtual double Area() {
</strong>        return 0;
    }  
}
  
public class Circle : Drawing {  
    public double Radius { get; set; }  
    public Circle() {  
        Radius = 5;  
    }  
<strong>    public override double Area() {        // Method Overriding
</strong>        return (3.14) * Math.Pow(Radius, 2);  
    }  
}  
  
public class Square : Drawing {  
    public double Length { get; set; }  
    public Square() {
        Length = 6;  
    }  
<strong>    public override double Area() {        // Method Overriding
</strong>        return Math.Pow(Length, 2);  
    }  
}  
  
public class Rectangle : Drawing {
    public double Height { get; set; }  
    public double Width { get; set; }  
    public Rectangle() {  
        Height = 5.3;  
        Width = 3.4;  
    }
    public override double Area() {        // Method Overriding  
        return Height * Width;  
    }  
}  

class Program {  
    static void Main(string[] args) {  
        Drawing circle = new Circle();          // Late Binding
        Console.WriteLine("Area :" + circle.Area());  
  
        Drawing square = new Square();          // Late Binding
        Console.WriteLine("Area :" + square.Area());  
  
        Drawing rectangle = new Rectangle();    // Late Binding
        Console.WriteLine("Area :" + rectangle.Area());  
    }  
}  
</code></pre>

<figure><img src="https://1151231797-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MQAaqgCwmb83T8T0x2j%2Fuploads%2FB7VaDmR16ETorwbt8Eeq%2Fimage.png?alt=media&#x26;token=ea1981ba-c718-4694-8a5c-d5106640baf8" alt=""><figcaption></figcaption></figure>

## Abstraction

**Abstraction** is the process to hide the internal details and show only the functionality.

* The keyword `abstract` is used before the class or method to declare the class or method as abstract.
  * An Abstract method is a method without a body.&#x20;
  * The implementation of an abstract method is done by a derived class.&#x20;
  * When the derived class inherits the abstract method from the abstract class, it must override the abstract method.

> **Abstraction** is the concealment of unnecessary program details so that the user only sees the essential attributes.

{% hint style="info" %}
The **Abstract** class and **Interface** both are used to have abstraction.
{% endhint %}

```csharp
class program {  
    abstract class Animal {  
        public abstract void Eat();  
        public void Sound() {  
            Console.WriteLine("dog can sound");  
        }  
    }  
    class Dog : Animal {  
        public override void Eat() {
            Console.WriteLine("dog can eat");  
        }
    }
} 
```

{% hint style="info" %}
An **Abstract** class can have non-abstract Methods(concrete methods) and declare variables while in case of **Interface** all the methods has to be abstract and there should not be any implementation.
{% endhint %}

## Encapsulation

**Encapsulation** refers to the bundling of data/properties with the methods that operate on that data, or the restricting of direct access to some of an object's components.

* Encapsulation is used to hide the values or state of a structured data object inside a class, preventing direct access to them by clients in a way that could expose hidden implementation details or violate state invariance maintained by the methods.
* Encapsulation is achieved by taking advantage of the _access modifiers_ that include _public_, _private protected_, _private_, _internal_, and _protected_ that control the visibility and accessibility of the members of a class.

> **Encapsulation** is the bundling of data, including the methods that operate on that data, into a single, private unit

<pre class="language-csharp"><code class="lang-csharp">public class Account {
<strong>    private string accountNumber;
</strong><strong>    private decimal balance;
</strong>    
    public Account(string accountNumber, decimal balance) {
        this.accountNumber = accountNumber;
        this.balance = balance;
    }
    public decimal GetBalance() {
        return balance;
    }
    public void Deposit(decimal amount) {
        balance += amount;
    }
    public void Withdraw(decimal amount) {
        if (balance >= amount)
            balance -= amount;
    }
}
</code></pre>

> In this example, the `Account` class has two private members: `accountNumber` and `balance`. These members are not accessible from outside the class. The class provides public methods `GetBalance()`, `Deposit()`, and `Withdraw()` to allow outside code to interact with the object.

{% embed url="https://www.youtube.com/watch?v=pTB0EiLXUC8" %}

{% embed url="https://www.interviewbit.com/oops-interview-questions/" %}

<details>

<summary>How to Approach</summary>

1.  Handle Ambiguity

    Depending When being asked an object-oriented design question, you should inquire _**who**_ is going to use it and _**how**_ they are going to use it. \
    Depending on the question, you may even want to go through the "six W's": **who**, **what**, **where**, **when**, **how**, **why**
2. Define the Core Objects
3. Analyze Relationships
4. Investigate Actions

</details>
