We will examine OOP (Object Oriented Programming) in this article and check on what it has.
The OOP helps us to develop structural, flexible, secure, and maintainable projects which mean companies reduce software expenses. (No doubt OOP is so important)
Let’s get started by checking what OOP is and how many elements it has
Most people start explaining OOP with objects(because everything is coming from objects).
However, I would like to get started with class because the class is a blueprint that consists of methods, properties, fields, and so on.
Computer.cs
public class Computer
{
public Computer() // Constructor
{
}
private decimal? _price; // field
public decimal? Price// Property
{
get
{
return _price;
}
set
{
_price = value;
}
}
public decimal? GetPrice()//method
{
return Price;
}
}
As you can see, the class has its own constructor, field, property, and method.
Now, we will use the Computer class to create an Object.
An object is an instance of the class which is why I wanted to start with class.
Program.cs
Computer laptop = new Computer()
{
Price = 15
};
laptop.GetComputerPrice();
A laptop is an object and we created it using the Computer class.
Now, we have an object and we need to manipulate it using OOP pillars which are inheritance, polymorphism, abstraction, and encapsulation.
Because OOP helps us to think of the objects in terms of real life. We have an object which is called the computer.
Let’s think of the laptop in real life
- It has a processor and many companies have been working on a processor for many years using inheritance because first, they have to follow versions 1, 2, 3, and so on and inherit them from the previous version because inheritance creates a parent-child relationship. The previous version would be the parent of the new version.
- It has a keyboard that consists of a bunch of buttons and we use it to make an interaction with the laptop. However, whenever you hit a different button, you see a different result on the screen. This is the polymorphism because the button is working differently under different conditions.
- When you hit the button, you have no idea about what kind of electrical part is working, this is the abstraction because the producer of the laptop shows you only what is necessary and hides the background process
- If you want to check for what is inside of the laptop, you will see a big card and a bunch of electrical parts on it which is encapsulation because the producer of the laptop only shows you the electrical part, not the logic and complex structure. (if you try to take off a tiny electrical part on the board, your computer will be dead because the electrical part is linked to a complex logic behind it)
Inheritance: a parent-child relationship
Polymorphism: An object can behave differently under different conditions
Abstraction: Show only what is necessary
Encapsulation: Hide complexity.
Let’s dive into the details
What is Inheritance and why do we use it?
Inheritance creates a relationship between two classes which are called Parent (or base class)and Child (or derived class). Whenever you inherit a class, the derived class automatically gets all properties and methods of the base class.
Inheritance is important because it helps us to have reusable codes.
The parent is used for deriving another class.
The Child is derived from the parent class.
Laptop.cs
public class Laptop:Computer
{
// you can put your logic here
}
As you can see from the above, there is no logic in the laptop(Child) class. However, you can reach properties and methods that are coming from the Computer(Parent) class once you create an instance of the laptop class.
Program.cs
Laptop brandLaptop = new Laptop()
{
Price = 20
};
brandLaptop.GetComputerPrice();
There are four different types of inheritance which are;
Single Inheritance
You have only one parent class and the derived class is inherited from the parent class.
Laptop.cs
public class Laptop:Computer
{
// you can put your logic here
}
Multiple Inheritance
You have at least two parent classes and the derived class is inherited from these two parent classes.
However, you can use only one abstract class for an inheritance, the others have to be the interfaces.
IKeyboard.cs
public interface IKeyboard
{
void DefineTypeOfKeyboard();
}
Laptop.cs
public class Laptop : Computer, IKeyboard
{
// you can put your logic here
public void DefineTypeOfKeyboard()
{
throw new NotImplementedException();
}
}
Multilevel Inheritance
You have only one parent class and your first derived class is inherited from the parent class. The second derived class is inherited from the first derived class.
BusinessLaptop.cs
public class BusinessLaptop : Laptop
{
// logic here
}
In this case, the Computer class is our parent class. The Laptop class is inherited from the Computer class and the BusinessLaptop class is inherited from the Laptop class. This is how multilevel inheritance works.
Hierarchical Inheritance
You have only one parent class and your all derived classes are inherited from the parent class.
BusinessLaptop.cs
public class BusinessLaptop : Laptop
{
// logic here
}
GamingLaptop.cs
public class GamingLaptop:Laptop
{
//logic here
}
In this case, imagine that the Laptop class is our parent class and others (BusinessLaptop and GamingLaptop)are derived from the Laptop class.
Sometimes you want to prevent your class from being inherited and you should use the sealed keyword in your class.
public sealed class SealedExampleClass
{
}
What is Abstraction?
Abstraction is showing only what is necessary for users and hiding the background processes or details.
Computer.cs
public class Computer
{
public Computer() // Constructor
{
}
private decimal? _price; // field
public decimal? Price// Property
{
get
{
return _price;
}
set
{
_price = value;
}
}
public decimal? GetComputerPrice()//method
{
if(CheckPrice()&& IsPermission())
{
return Price;
}
return 0;
}
private bool CheckPrice()
{
return true;
}
private bool IsPermission()
{
return true;
}
}
Program.cs
Laptop brandLaptop = new Laptop()
{
Price = 20
};
brandLaptop.GetComputerPrice();
As you can see above, the user can see the GetComputerPrice method but does not have any idea about the process in the GetComputerPrice. This is how abstraction works. (We will check on the abstract keyword later)
What is Encapsulation?
Encapsulation is a way to hide complexity from the outside. If you check the Computer class, the user can access the CheckPrice and IsPermission methods because they are marked as public which is accessible from outside. Once you make them private, nobody can access them from outside and also you achieve encapsulation.
Also, the get-set method is a kind of encapsulation
Computer.cs
public class Computer
{
public Computer() // Constructor
{
}
private decimal? _price; // field
public decimal? Price// Property
{
get
{
return _price;
}
set
{
_price = value;
}
}
public decimal? GetComputerPrice()//method
{
return GetPrice();
}
private bool CheckPrice()
{
// logic here and return the value
return true;
}
private bool IsPermission()
{
return true;
}
private decimal? GetPrice()
{
if(CheckPrice() && IsPermission())
{
return Price;
}
return 0;
}
}
As you can see, GetComputerPrice only executes GetPrice because we hide the other processes from the outside. This is how encapsulation works.
Also, the get-set method is an example of encapsulation because the _price is an important field and nobody can access the field directly.
private decimal? _price; // field
public decimal? Price// Property
{
get
{
return _price;
}
set
{
_price = value;
}
}
What is Polymorphism?
Polymorphism is the way to behave differently under different conditions. You can use the same functions with different signatures(parameters) or different return types.
Let’s go back to the Laptop.cs and create some methods
Laptop.cs
public class Laptop : Computer, IKeyboard
{
// you can put your logic here
public void DefineTypeOfKeyboard()
{
throw new NotImplementedException();
}
public decimal? GetPrice(decimal Tax)
{
return Price + (Price * (Tax / 100));
}
public decimal? GetPrice(decimal Tax, string color)
{
if (color == "Red")
{
Price = Price + 1;
}
else
{
Price = Price != 0 ? Price - 1 : 0;
}
return Price + (Price * (Tax / 100));
}
}
As you can see, we can use the same class with different signatures. If you want you can use the same class with a different return type. This is how polymorphism works. Also, this is an example of overloading.
Overloading is a way to implement polymorphism in the same class. You have a method and you use the method with different parameters and return types.
Overloading is a compile time polymorphism
Overriding is a way to implement polymorphism in the different classes. However, in this case, you can use the same method with the same signature you cannot change the signatures.
Overriding is a run-time polymorphism.
In addition, if you want to override a method in the derived(child) class, you have to use the virtual keyword in the parent(base) class.
Let’s make an example of overriding methods
We create a virtual method in the Computer.cs and access it in the Laptop.cs
Computer.cs
public virtual void ComputerType(string type)
{
// base class
}
Laptop.cs
public override void ComputerType(string type)
{
base.ComputerType(type);
// you can change logic here
}
If you wonder what is the difference between overloading and overriding
- Overloading is implemented in the same class. Overriding is implemented in different classes.
- Overloading can be implemented with different signatures, however, overriding has to be implemented with the same signatures.
- You do not have to use any specific keyword to achieve overloading, however, in order to achieve overriding, you have to use the virtual keyword in the parent class.
- Overloading does not need inheritance because all processes are done in the same class. However, overriding needs inheritance because all processes are done in different classes.
Let’s say that you do not want to override the method in the child class because you want to use the method name that comes from the parent class for different logic. In this case, you have to use method hiding.
In order to achieve method hiding, you should use the new keyword instead of override.
Laptop.cs
public new void ComputerType()
{
// logic here
}
As you can see, we can use the same name in the child class without getting errors because we are using method hiding.
Maybe you will never run into this issue because method hiding is an advanced topic of polymorphism
I tried to explain the main concept of OOP in C# in this article and I hope it will be useful.
Code: https://github.com/frttnk/Main-Concept-of-Object-Oriented-Programming-in-C-sharp