Introducing Object-Oriented-Programming
Tags: dotnet, csharp, beginners, programming
Published: 2023-02-09 11:11:59

If you are new to programming , or you already have some experience , then you may wanna spend some time studying what so called Software Design Paradigms , which are different techniques developers would use to write software in a more organized manner , one of these paradigms is Object-Oriented-Programming or **OOP** for short , so , what is OOP ? let's talk about it 


## Overview of OOP 
Object-Oriented-Programming (OOP) is a software design paradigm that's used to develop applications that are based on objects interacting with each other , it's also widely used and adopted by many programming languages like **C# , Java , Ruby and Python** just to name a few , the list goes on though , cause OOP is a very important paradigm in modern software development.

With the overview out of the way , we'll see what this article covers:

**1:** A definition of OOP according to the internet.
**2:** The fundamentals of OOP.
**3:** What are classes ? And how to create them in C#
**4:** The 4 main pillars of OOP with examples in C#.
**5:** The benefits of using OOP.


## 1: OOP Definition According To The Internet

> Object Oriented Programming is a programming paradigm that focuses on the use of objects and classes to create programs. Objects are entities that can be manipulated and can get hold of data. Classes are groupings of objects that share similar properties and behaviors. In object-oriented programming, a program is created by combining objects and classes to form a structure. This structure provides the foundation for the program to be built upon.

This definition is really simple and straight forward , it provides adequate info on what's OOP and how it works.

The word **Classes** mentioned in the definition is a crucial point in OOP , which we'll be discussing shortly.

Ok , we've defined OOP , now let's move to the second point.


## 2: The fundamentals of OOP 
We won't be spending so much time here , cause all of this will be plain theory , and the best way to learn OOP is by writing some code , so let's just cover some ideas here and then move to OOP in action.

The fundamental point of OOP is that everything can be identified is an object , a human can be object , a car , maybe an employee , and the company that the employee works for, and the whole concept of OOP is just objects dealing and working together to build the application , these object can communicate and send data back and forth between them , this might sound a bit ambiguous and vague cause we still haven't discussed objects or classes yet , but yeah , bear with me , everything will become more apparent as we move forward.

Onto the third point we move


## 3: Classes and Objects in **C#**
Ok , now we got to the exciting part , let's introduce the concept of a **Class** in C#.

**Classes** : Classes are the foundation and the backbone of OOP in C# , a class essentially groups properties and behaviors of an object , which means that a class defines the structure of objects that will be created as instances of that class.

Classes in C# are composed of various members , like private fields , properties , constructors and methods.

We talked about classes , and we said they define the structure of objects , so what are objects ?
 
 **Objects** : An object is an instance of a class , this instance holds all the properties and behaviors the class has defined , I think an example will help clearing up the picture.

**Creating a car class and instances of it**
Let's build a car class , so ask yourself , what kind of information we can put together that we can use in a program that makes up a car ?
Well , a car has a manufacturer that produced it , and a model , the year of production , and maybe the number of doors it has.

Let's code our first class , you can use a console application to keep things minimal , create a new one and outside of the Program class which is the main class of any C# project , outside of it , you can add the following code:

```

public class Car
{
  public string ManufacturerName {get; set;}
  public string Model {get; set;}
  public int YearOfProduction {get; set;}
  public int NumOfDoors {get; set;}
}

```

Ok , if you're experienced with C# , this would be super easy for you to understand , but , in case you're new to this , I'll break it down for you .

**public** is an access modifier , when a class is public then it's accessible anywhere in the project , also accessible for other projects if they reference our project where this class is defined , there are various access modifiers like **private** , private is the default access modifier for class members in case no modifier was explicitly specified , this implies that those members are only accessible within their class and aren't exposed to other types , **internal** , **protected** , **protected internal** , and lastly **private internal**.
I won't be explaining all of them , but I advise you to read this article which covers all of them:

https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/access-modifiers

Ok , let's move on
I won't be explaining what a string is cause I assume you already know since it's something you learn in day 1.

Then we have a name like **ManufacturerName** , there's a naming convention you should follow when naming **Properties** which is to capitalize every first letter of a word even the first word , this convention is known as **Pascal Case** , and lastly , this portion

`{get; set;}`
Ok , I mentioned that this is a property , this whole line :
`public string ManufacturerName {get; set;}`

Well , this is called auto-implemented property , this property has 2 methods called **Getters & Setters** which are the **get;** and **set;** that exist within the curly brackets , but what do they get and set ?
In auto-implemented properties , the compiler generates a private field that you can't see in your code , and when you call the property to get its value , it returns the value assigned to the private field using the **get** method , and when you want to set a value to the property , the **set** method is called, the following code is a depiction of what it looks like if you were to do that manually instead of using auto-implemented properties :

```

public class Car
{
  private string manufacturerName;
  
  public string ManufacturerName 
  {
    get { return manufacturerName; }
    set { manufacturerName = value; }
  }	
}

```
This is how it works if you didn't want to use the auto-implemented properties feature , this might be useful in case you wanted to apply some restrictions on the value to be set for the field , like you don't want the name to be longer than 100 characters for example , you would do that like this:

```

public class Car
{
  private string manufacturerName;
  
  public string Manufacturer 
  {
    get { return manufacturerName;}
    set 
    { 
      if(value.Length > 100)
      {
        manufacturerName = "Invalid Name";
      }
      else
      {
        manufacturerName = value;
      }
    }
  }	
}

```
That was a lot of code , I would advise to always use Auto-Implemented to let the compiler do the work for you , unless there's a massive necessity for adding limitations on the received value.


Now our class is defined , it's ready to be used to create new object instances of it.

Go to Main and add this:

```

Car bmw = new()
{
  ManufacturerName = "BMW",
  Model = "740M",
  YearOfProduction = 2021,
  NumOfDoors = 4
};

```

Ok we'll go back to our car class and override a method called **ToString();** , you might wonder where this method came from , well , it came from the **Super class/Base class** known as **Object** , all types in C# derive from this base class even without you explicitly adding it , we will talk more about deriving classes and base classes ahead in the article , but just know where this method has come from for now.

Add this code to the bottom of your Car class:

```

public override string ToString()
{
  return $"{ManufacturerName} {Model} was produced in {YearOfProduction}";
}

```

Now back to Main , you can do a console write line to log the car information to the console , like this:

```

Console.WriteLine(bmw.ToString());

```

This will print the info of our car object to the console.

**AMAZING**
You created a class and you used it to instantiate an object , you can use this class to create as many instances as you want.

Let's move to the next point of our OOP journey


## 4: The Main Pillars Of OOP

There are 4 pillars for OOP that you should be extremely aware of , which are:

1: **Encapsulation**
2: **Abstraction**
3: **Inheritance**
4: **Polymorphism**


Let's explain them.
In our previous car example , we've used both **Encapsulation & Abstraction** . But how ?

Well , encapsulation means as the name suggests , encapsulating , but encapsulating what ?
In the context of OOP , it's encapsulating relevant members together in one large capsule you can say , which is a class in this case , if you gaze back at our Car class , it contained relevant members that all together represent the entity of our car , so this is **Encapsulation** , pretty easy right ?

Now what about the concept of **Abstraction** ? As I said , we came across this concept too within our example , let's see how.

If you take a car in the real world , how many properties will you be able to identify ? The answer is: **Numerous**. 
A car has lights , wheels , wheel size , interior , interior color , engine , engine capacity , wires , exhaust , chassis , mirrors , and loads more , but our Car class didn't have any of these properties , we merely had a couple of properties , like the model , number of doors and 2 others , but why ? Well , that's **Abstraction** , in action , nice rhyme tho 😂.

In the context of our app , we identified the use case for our Car class , which is basically to hold some typical info for our car that we can display for our end user , but what if we were working per say , on a **Car Selling Website** ? Our context would change , and our Car class will also change , at that time , we would need to re abstract our class , again , remove some information that isn't necessary for us and encapsulate information that matters , like a collection of strings representing the car specs , the engine condition , car color , the mileage it has , and the price , in other words , include what matters and exclude the rest , that's how I like to think of Abstraction.


Now we come to our third concept: **Inheritance**
Again , you have seen that in our demonstration up there , when we overrode the **ToString()** method , and I stated that this method came from a base class named **Object** , this was **Inheritance** in it's basic form , our Car class was derived from the base class Object , that happened implicitly though , we could've done it explicitly like this :

```

public class Car : Object 
{ }

```

But this part is automatic so there's no need for us to code it , but what if we want to apply inheritance ourselves ? Can we do that ? Yeah , we can , and it's very easy.

For this concept , our car class will be retired finally , let's give it a warm bow as it served us for a decent while , for this example , we will use an Animal base class.

Create a new class and call it Animal , it'll be our base class , parent class , super class , which ever name floats your boat , add the following properties to it :

```

public class Animal 
{
    public string Name {get; set;}
    public int Age {get; set;}
}

```

In this example , we will see both **Inheritance & Polymorphism** all together.
Now , create a new class and call it Dog , like this :

```

public class Dog : Animal
{
    public string Breed {get; set;}
    
    public void Bark()
    {
        Console.WriteLine($"{Name} says Woof Woof !");
    }
}

```

Ok , to inherit from a class , the syntax is pretty basic , just like this:
`public class ClassName : ClassToInheritFrom`

We give the class a name , then a colon , then we specify the name of the class from which we are deriving our new class , pretty simple right ?

Now if you take a look at the **Bark** method our Dog class has , you can tell we are using the Name property without us having it in our Dog class ? How comes , well , it came from the **Animal** base class , see , this is how simple inheritance is , let's see more , create another class called **Cat** and derive it from **Animal** base class , just like this:


```

public class Cat : Animal
{
    public string FurColor {get; set;}
    
    public void GoMeow()
    {
    	Console.WriteLine($"{Name} says MEOW !");
    }
}


```

Ok , to summarize inheritance , we inherit members from a base class in our case it's **Animal** , and we extend on it , that's it , straight plain simple !.


Lastly , **Polymorphism**.
Fortunately , we've covered that through our **Animals** example , let's go to Main and see how.

Create an array and call it animals , like this:

```

Animal[] animals = new Animal[]
{
  new Dog {Name = "Ace" , Age = 2 , Breed = "Chow-chow"},
  new Cat {Name = "Bella" , Age = 5 , FurColor = "Brown"},
  new Cat {Name = "Oliver" , Age = 1 , FurColor = "White"}
};


```

Ok how did we add Dogs and Cats to an array of type Animal ? Aren't they different types ? Well , not really , our Dog and Cat types inherit from Animal , and through **Polymorphism** , it's possible for the base type to be many different types , our Animal base class can be of different forms and shapes right now.

_Let's pause for a second for an English session_

What does the word **Polymorphism** even mean ?

According to the Oxford Language Dictionary , it means the following :

> The condition of occurring in several different forms.

Well I reckon that this definition clears the idea of Polymorphism !

I'll give you another example while we're at it so you understand the concept even more , try to think of a vehicle , a vehicle could be a base class , and we can morph it into many forms , like a sedan car , sports car , bus , truck , a tow car maybe , so again , vehicle can be multiple different forms and shapes. 


Ok , we have reached the final point.

## 5: The benefits of using OOP
Object Oriented Programming offers several advantages.
 
**Firstly** : it is easier to maintain a program as all of the code is written in one place and can be easily modified.

**Additionally**: Object-Oriented programs are more organized, as all of the data and behaviors are encapsulated in objects, making it easier to debug and maintain the application. 

Object Oriented Programming also allows for better code re-use, as the same code can be used in multiple applications. 

**Finally**: Object Oriented Programming provides better security, as all of the data and behaviors are encapsulated in objects, making it more difficult for malicious code to access the data.
 

This was a truly long article , it was long to write and long to read , but it was so much fun for me to write and I hope it's as fun for you to read.


For now , GOODBYE NERDS !