OOPS Concepts In C#: Object Oriented Programming Concept Tutorial

By Sruthy

By Sruthy

Sruthy, with her 10+ years of experience, is a dynamic professional who seamlessly blends her creative soul with technical prowess. With a Technical Degree in Graphics Design and Communications and a Bachelor’s Degree in Electronics and Communication, she brings a unique combination of artistic flair…

Learn about our editorial policies.
Updated March 7, 2024

This Tutorial Explains The OOPS Concepts In C#. You Can Learn About Object Oriented Programming Principles Like Polymorphism, Encapsulation, Inheritance & Abstraction:

Object-Oriented Programming is a programming model that works on a principle that revolves around objects rather than action or logic. It allows the users to create objects based on the requirement and then create methods to operate upon those objects.

Working on these objects to obtain the desired result is the goal of object-oriented programming.

=> Explore The Entire Series Of C# Training Tutorials Here

OOPS Concepts in C#

Let’s revise some of the concepts that we learned in our earlier tutorials!!

Namespace

A namespace in C# is a collection of classes. It provides a structure to keep one class name separate from another class name by declaring them in a different namespace. So that the classes with the same name don’t conflict with one another.

Class

A Class is a blueprint of a data type. It is actually a collection of objects. It contains objects and the definition for the operation that needs to be performed on that object.

Objects

Objects are the instances of the class.

In our previous tutorials, we have already learned about Class and Objects in detail.

OOPS Concepts In C#

Object-Oriented Programming offers several advantages over the other programming models like:

  1. The precise and clear modular approach for programs offers easy understanding and maintenance.
  2. Classes and objects created in the project can be used across the project.
  3. The modular approach allows different modules to exist independently, thereby allowing several different developers to work on different modules together.

In this tutorial, we will be focusing more on other major core OOPS concepts:

  1. Encapsulation
  2. Polymorphism
  3. Inheritance
  4. Abstraction

Encapsulation

Encapsulation is an object-oriented programming concept that allows programmers to wrap data and code snippets inside an enclosure. By using the encapsulation program, you can hide the members of one class from another class. It’s like encircling a logical item within a package. It allows only relevant information available and visible outside and that too only to specific members.

Encapsulation is implemented by using access specifiers. Access Specifier is used for defining the visibility and accessibility of the class member in C#.

C# contains the following access specifiers.

  • Public
  • Private
  • Protected
  • Internal

The access specifiers define the visibility of the class and its values. It allows you to make data visible for a particular part of the code and hide it from another part. The most commonly used visibility is public and private.

Let’s have a look at them.

Public: The public keyword allows its members to be visible from anywhere inside the project. This access specifier has the least visibility restriction.

Private: The private members can only be accessed by the member within the same class. This has one of the most restricted visibility.

Protected: Protected accessibility allows the member to be accessed from within the class and from another class that inherits this class.

Internal: Internal provides accessibility from within the project. Another similar internal accessibility is protected internal. This allows the same as the internal and the only difference is that a child class can inherit this class and reach its members even from another project.

Polymorphism

Polymorphism is derived from the Greek dictionary, it means one with many forms. Poly stands for many and Morph means forms. It allows the class in C# to have multiple implementations with the same name.

Polymorphism is basically divided into two parts:

  1. Compile-time Polymorphism
  2. Run time polymorphism

#1) Static or Compile Time Polymorphism

Compile-time polymorphism is also known as Static polymorphism. Method overloading is one of the ways in which compile-time polymorphism is achieved. It is known as compile-time polymorphism as the method calling decision is made at the time of compiling.

It is achieved by keeping the method name the same but passing different sets of parameters. In method overloading, the system first checks the parameter used and based on the set of parameter it decides to call the appropriate method.

Example:

class Program {
void print(int i, int j) {
Console.WriteLine("Printing int: {0}", (i+j) );
}
void print(string a, string b) {
Console.WriteLine("Printing String: " , (a+b));
}
      
static void Main(string[] args) {
Program prog = new Program();
         
// Call print for sum of integers
prog.print(5, 6);
         
// Call to concatenate strings
prog.print("Hello","World");
Console.ReadKey();
}
}

In the above example, we have called the same method “print” twice using different parameters. At first, we pass two integers as parameters, then we have passed two strings as parameters. There are two “print” methods with the same name.

When we pass a parameter with the integers system, it will look for the method named “print” which accepts two integer parameters and it will execute that ignoring other methods with the same name.

In the second part, we passed the string parameter. Again the system will look for the method that accepts two string parameters. Hence, based on the parameters passed, the first method will add two integers and the next one will concatenate two strings.

#2) Dynamic Polymorphism or Runtime Polymorphism

Runtime polymorphism or dynamic polymorphism occurs when both method name and method signature have the same name and parameters. Method overriding is an example of dynamic polymorphism. It allows the user to create an abstract class with partial interface implementation.

Method overriding is achieved using inheritance. To achieve method overriding both the base class and derived class should have the same name and parameter. During compile time the compiler is not able to recognize the overriding method, hence, it doesn’t throw any error. The decision to run a method is taken during runtime.

Example:

class Program
 {
public void print()
         {
               Console.WriteLine("Printing from class Program");
          }
 }
class Execute : Program
 {
public void print()
         {
                 Console.WriteLine("Printing from class Execute");
         }
        
public static void Main(string[] args)
                {
                        Execute exe = new Execute();
                         exe.print();
                        Console.ReadLine();
                }
  }

If we run the above program we will get the following output:

Printing from class Execute

Even though the class Execute has inherited all the methods of the class Program but when we called the method print which is present in both the classes, the method present in the child class will override the method from the parent class.

Dynamic polymorphism is used to implement abstraction. It allows the user to create an abstract class that is used to provide an implementation for an interface when it is inherited by a derived class. The abstract class can contain names/signature of the methods and the derived class can have a more specialized definition for the method.

Inheritance

Inheritance is an important part of the OOPS concept. In inheritance, we define parent and child classes. The child class can inherit all the methods, objects and properties of the parent class. A child class can also have its own methods and specific implementation.

The parent class is also known as a base class and the child class that inherits the base class is also known as derived class.

Example:

class Program
       {
public void print()
             {
                Console.WriteLine("Printing from class Program");
              }
       }
               class Execute : Program
      {      
       
public static void Main(string[] args)
               {
                       Execute exe = new Execute();
                       exe.print();
                       Console.ReadLine();
                }
}

Here, we have a class named as a program that has one method. We have another class Execute that inherits the class Program. The class Execute is the derived class and the class program is known as the base class.

Now, instead of creating an object instance for the class program, we have created an object instance for class Execute. Using this instance we can access the print method from the base class.

So, the output of the above code will be:

Printing from class Program

The derived class doesn’t only inherit methods, it also inherits nearly all class members like fields, properties, etc. depending upon the visibility. Inheritance in C# doesn’t allow the use of multiple inheritances i.e. one class cannot inherit from several different classes, however, one class can inherit from another class which can inherit from a different class.

Abstraction

Abstraction is one of the major principles of Object-oriented programming. Abstraction allows the programmer to display only the necessary details to the world while hiding the others. Abstraction is achieved in C# by using the Abstract class and interface.

A class can be declared as an abstract class by using the “Abstract” keyword. The Abstract class in C# is always the base class in the hierarchy. What makes them different from the other class is that they cannot be instantiated. A C# abstract class needs to be inherited.

Example:

        
class Program
    {
           static void Main(string[] args)
           {
                  Hyundai hyn = new Hyundai();
                  String descp = hyn.Describe();
                  Console.WriteLine(descp);
                  Console.ReadKey();
            }
      }
abstract class Car
 {
          public void Describe()
          {
                return "Description of the car";            
           }
   }

class Hyundai : Car
{
}

The output of the following is:

Description of the car

If you compare it with our previous examples during inheritance or dynamic polymorphism, then you will find the similarities. The most recognizable difference is the use of abstract keyword before the class Car. In case you want to override this or provide your own implementation similar to what we did in dynamic polymorphism. Then you can achieve that by the following.

class Program
{
           static void Main(string[] args)
           {
                Hyundai hyn = new Hyundai();
                String descp = hyn.Describe();
                Console.WriteLine(descp);
                Console.ReadKey();
            }
 }
abstract class Car
{
              public virtual string Describe()
              {
                      return "Description of the car";
               }
   }
class Hyundai : Car
{
         public override string Describe()
         {
                 return "Description of the car is now Hyundai";
          }
 } 

So, if you execute this code now, it will give the following output:

Description of the car is now Hyundai

The derived class method overrides the base class method. In this way, you can create a different derived class such as Ferrari, Porsche, BMW, etc. with their own implementation methods.

If you look closely, you can see that our description method in the abstract class doesn’t contain any implementation.

Then, why are we defining empty methods?

This is because an Abstract class provides a signature of the methods and makes it an obligation for the subclasses to create an implementation for all of these methods. This allows sharing of the base class but at the same time, it also keeps a check on the method implementation of the derived class.

Interface

In C#, the interface is the blueprint of a class. The interface is similar to an abstract class and is used to achieve a hundred percent abstraction. All the methods described inside the interface are abstract by default. It doesn’t have any method body and it cannot be instantiated.

The interface is mainly used to achieve multiple inheritance and full abstraction. All the method signature declared inside the interface should be provided with implementation from the class or the struct that implements it.

Example:

class Program
{
           static void Main(string[] args)
          {
                 Hyundai hyn = new Hyundai();
                 String descp = hyn.Describe();
                 Console.WriteLine(descp);
                 Console.ReadKey();
            }
}
interface Car
 {
       string Describe();
             
  }
class Hyundai : Car
  {
         public string Describe()
         {
                return "Description of the car is now Hyundai";
           }
  }

The output of the above code will be:

Description of the car is now Hyundai

Here, we have created an interface Car. As the interface cannot have any method definition, we have just provided the method name and return type in the interface. We then implemented the interface Car to another class Hyundai. In the implemented class we provided the definition for the methods defined inside the interface.

Conclusion

In the Object-Oriented Programming concept, each part of the program is treated as an object. Class is a collection of similar types of elements and an object is the instance of the class.

Encapsulation in C# allows the user to establish the visibility of the class and its members. Polymorphism allows the methods to have the same name but with different parameters inside the same class or with the same parameter in a different class.

Inheritance is when a child class which is also known as the derived class inherits all the properties including methods, objects, fields, etc. of the parent class which is also known as the base class. Abstraction allows the program to display just the signature while hiding the implementation details.

Consolidated Program

class Program
     {
             void print(int i, int j)
             {
                   Console.WriteLine("Printing int: {0}", (i + j));
              }
            void print(string a, string b)
            {
                   Console.WriteLine("Printing String "+ a + b);
             }
static void Main(string[] args)
             {
                   Program prog = new Program();
                
                   // Call print for sum of integers
                   prog.print(5, 6);
               
                   // Call to concatenate strings
                   prog.print("Hello", "World");
                
                   Hyundai hyn = new Hyundai();
                   String descp = hyn.Describe();

                   Console.WriteLine(descp);
                   Console.ReadKey();
              }
     }

abstract class Car
  {
           public virtual string Describe()
           {
                  return "Description of the car";
            }
   }

class Hyundai : Car
 {
             public override string Describe()
             {
                     return "Description of the car is now Hyundai";
             }
 }

=> Explore The Entire Series Of C# Training Tutorials Here

Was this helpful?

Thanks for your feedback!

Leave a Comment