Object-Oriented Programming (OOP) is the foundation of modern C# development. Whether you're building console apps, web applications, desktop software, or APIs, you are constantly working with classes, objects, methods, and inheritance.
This article walks step-by-step through OOP in C#:
Basic program elements (identity, variables, methods)
Classes and objects
Static vs instance members
Constructors and this
Access modifiers and encapsulation
Inheritance, base, method overriding
Polymorphism (overloading and overriding)
Sealed classes
Abstraction and abstract classes
Interfaces and multiple inheritance through interfaces
1. Program Elements in C#
Before OOP, you must understand what a program is made of. A program is a set of instructions that consists of:
Identity
Variables
Methods
1.1 Identity
An identity is the name given to a program component:
Program name
Class name
Variable name
Method name
These names are used to reference and access those members.
1.2 Variables – "Named Memory Locations"
A variable is a name given to a memory location used to store data.
string name = "Amar";
int age = 23;
double salary = 35000.00;
bool married = false;
string, int, double, bool are data types.
name, age, salary, married are identities for each memory location.
Variables store the state (data) of your program or objects.
1.3 Methods – "Blocks of Logic"
A method is a block of instructions with a name. It:
int Add(int a, int b)
{
int c = a + b;
return c;
}
Here:
2. Introduction to Object-Oriented Programming in C#
C# is a fully object-oriented language. OOP is about defining objects and establishing communication between them.
There are four main principles of OOP:
Encapsulation: binding data and methods together
Inheritance: reusing members of one class in another
Abstraction: hiding implementation details, exposing only necessary features
Polymorphism: one object behaving differently in different situations
We implement these principles using classes and objects.
3. Classes and Objects
3.1 Class – The Blueprint
A class is a blueprint or template. It defines data (variables) and behavior (methods).
class Account
{
long number;
double balance;
void Withdraw()
{
// logic
}
void Deposit()
{
// logic
}
}
A class itself is not an object; it just describes what objects of that type look like.
3.2 Object – An Instance of a Class
An object is a runtime instance of a class. Its instance variables get memory when the object is created.
Account acc = new Account();
Account → class
acc → object (instance)
You can create multiple objects from the same class model.
4. Types of Variables in C#
In C#, variables are categorized to reflect scope and usage:
Static variables: shared across all objects
Instance variables: unique per object
Method parameters: input to methods
Local variables: temporary data inside methods
4.1 Static Variables
Declared with the static keyword inside a class.
Shared by all instances of the class.
Accessed by using the class name.
class Bank
{
public static string BankName = "AXIS";
}
Usage:
Console.WriteLine(Bank.BankName);
Static variables are automatically initialized with default values based on their types (0, 0.0, false, null, etc.).
4.2 Instance Variables
class Employee
{
int id; // instance variable
string name; // instance variable
}
Each Employee The object has its own id and name.
4.3 Local Variables & Method Parameters
int Add(int a, int b) // a and b are parameters
{
int c = a + b; // c is a local variable
return c;
}
5. Methods in Detail
Methods in C# are classified based on:
Examples
No arguments, no return value
With arguments, no return value
With arguments, with a return value
No arguments, with return value
C# also distinguishes between:
class Program
{
// Static method
static void Fun()
{
Console.WriteLine("Static Fun");
}
// Instance method
void Show()
{
Console.WriteLine("Instance Show");
}
static void Main()
{
Program.Fun(); // static
Program p = new Program();
p.Show(); // instance
}
}
6. Constructors and Object Creation
6.1 Constructor Basics
A constructor is a special method that:
class Employee
{
public Employee()
{
Console.WriteLine("Object created");
}
}
class Program
{
static void Main()
{
Employee emp = new Employee(); // calls constructor
}
}
6.2 Instance Methods
Any non-static method is an instance method and must be called on an object:
class Program
{
public static void Main()
{
Program obj = new Program();
obj.Fun();
}
void Fun()
{
Console.WriteLine("fun");
}
}
7. this Keyword and Parameterized Constructors
7.1 What is this?
this is a reference to the current object. It's used inside instance methods and constructors to:
class Program
{
int a;
Program(int a)
{
this.a = a; // left: instance, right: parameter
}
}
7.2 Parameterized Constructors
A constructor with parameters is called a parameterized constructor. It helps set initial values during object creation.
class Employee
{
int id;
string name;
public Employee(int id, string name)
{
this.id = id;
this.name = name;
}
public void Details()
{
Console.WriteLine($"{id}, {name}");
}
}
class Program
{
static void Main()
{
Employee e1 = new Employee(101, "Amar");
Employee e2 = new Employee(102, "Annie");
e1.Details();
e2.Details();
}
}
8. Access Modifiers in C#
Access modifiers define the visibility and accessibility of classes and members. C# supports:
public
private
protected
internal
protected internal
Quick Summary
public: accessible from anywhere in the project (and other projects that reference it).
private: accessible only within the same class.
protected: accessible within the class and its derived (child) classes.
internal: accessible within the same assembly (project).
protected internal: combination of protected and internal.
9. Encapsulation in C#
Encapsulation means protecting data within a class and exposing it only through methods.
Implementation rules:
Example
class Bank
{
private double balance;
public void SetBalance(double balance)
{
this.balance = balance;
}
public double GetBalance()
{
return this.balance;
}
}
This style is often called POCO (Plain Old CLR Object) in . NET.
10. Constructor Chaining with this()
Constructor chaining means one constructor calls another constructor in the same class using this().
class Test
{
public Test() : this(10)
{
Console.WriteLine("Zero-args constructor");
}
public Test(int x) : this(x, 20)
{
Console.WriteLine("One-arg constructor");
}
public Test(int x, int y)
{
Console.WriteLine("Two-arg constructor");
}
}
class Program
{
static void Main()
{
Test obj = new Test();
}
}
Output order illustrates how constructors chain from the most specific to the most parameterized.
11. Inheritance in C#
Inheritance allows you to create a new class by reusing members of an existing class.
Terminology:
11.1 Basic Example
class Employee
{
public void DoWork()
{
Console.WriteLine("Employee does work");
}
}
class Manager : Employee
{
public void MonitorWork()
{
Console.WriteLine("Manager monitors work");
}
}
class Company
{
static void Main()
{
Manager m = new Manager();
m.DoWork(); // from Employee
m.MonitorWork(); // from Manager
}
}
11.2 Types of Inheritance (Conceptual)
Single Inheritance – one parent, one child
Multi-level Inheritance – A → B → C
Hierarchical Inheritance – one parent, multiple children
Multiple / Hybrid – via interfaces in C# (classes cannot have multiple base classes).
12. this vs this() and base vs base()
this
this()
base
base()
class Parent
{
public Parent()
{
Console.WriteLine("Parent created");
}
}
class Child : Parent
{
public Child() : base()
{
Console.WriteLine("Child created");
}
}
13. Method Overriding and virtual / override
Method overriding is used to change the implementation of a method in a derived class.
Rules
class Parent
{
public virtual void Fun()
{
Console.WriteLine("Parent functionality");
}
}
class Child : Parent
{
public override void Fun()
{
Console.WriteLine("Child functionality");
}
}
class Program
{
static void Main()
{
Parent p = new Child();
p.Fun(); // calls Child.Fun() – runtime polymorphism
}
}
You can still access the parent implementation using base.Fun() inside the child.
14. base() and Initializing Parent Fields
When inheritance involves constructors with parameters, the child can pass values to the parent using base():
class Parent
{
public int a, b;
public Parent(int a, int b)
{
this.a = a;
this.b = b;
}
}
class Child : Parent
{
public int c, d;
public Child(int a, int b, int c, int d) : base(a, b)
{
this.c = c;
this.d = d;
}
public void Details()
{
Console.WriteLine($"Parent a: {a}, b: {b}");
Console.WriteLine($"Child c: {c}, d: {d}");
}
}
15. Polymorphism in C#
Polymorphism means "many forms" – an object behaving differently in different situations. It has two main types:
Compile-time polymorphism – Method Overloading
Runtime polymorphism – Method Overriding
15.1 Method Overloading (Compile-time Polymorphism)
Defining multiple methods with the same name but different parameter lists within the same class.
class Calculator
{
public void Add(int x, int y)
{
Console.WriteLine($"Sum of 2 numbers: {x + y}");
}
public void Add(int x, int y, int z)
{
Console.WriteLine($"Sum of 3 numbers: {x + y + z}");
}
}
The compiler decides which method to call based on the parameters.
15.2 Method Overriding & Upcasting (Runtime Polymorphism)
Runtime polymorphism is implemented via overriding and upcasting.
class Parent
{
public virtual void Behave()
{
Console.WriteLine("Parent behavior");
}
}
class Child : Parent
{
public override void Behave()
{
Console.WriteLine("Child behavior");
}
}
class Program
{
static void Main()
{
Parent p = new Child(); // upcasting
p.Behave(); // calls Child.Behave()
}
}
16. Sealed Classes, Methods, and Variables
The sealed A keyword is used to prevent further inheritance or overriding.
Sealed Class
sealed class A
{
}
// class B : A { } // error: cannot derive from sealed type
Sealed Method
class X
{
protected virtual void F1() { }
}
class Y : X
{
sealed protected override void F1() { }
}
// class Z : Y { protected override void F1() { } } // error
Sealing methods are useful when you want to allow overriding only once in the inheritance chain.
17. Abstraction and Abstract Classes
Abstraction hides internal implementation and shows only the necessary functionality.
An abstract class:
public abstract class Parent
{
public abstract void M1(); // abstract method
public void M2()
{
Console.WriteLine("Parent concrete method");
}
}
public class Child : Parent
{
public override void M1()
{
Console.WriteLine("Parent abstract method implemented");
}
}
You cannot create an instance of an abstract class directly. You must use a child class.
Abstract classes can also have constructor parameters and instance variables, which you can initialize using base() in the child, as shown in the notes.
18. Interfaces and Multiple Inheritance
An interface defines only abstract members (by default, methods are public abstract).
interface IFirst
{
void M1();
void M2();
}
Implementing an Interface
class Second : IFirst
{
public void M1()
{
Console.WriteLine("M1...");
}
public void M2()
{
Console.WriteLine("M2...");
}
}
You must mark implemented methods as public.
Multiple Inheritance via Interfaces
C# does not allow a class to inherit from multiple base classes, but a class can implement multiple interfaces.
interface A
{
void M1();
}
interface B
{
void M2();
}
class C : A, B
{
public void M1()
{
Console.WriteLine("M1...");
}
public void M2()
{
Console.WriteLine("M2...");
}
}
Here, C effectively has behavior from both A and Bachieving multiple inheritance through interfaces.
Final Thoughts
Object-Oriented Programming in C# revolves around:
Classes and objects to structure your application
Static and instance members to handle shared vs per-object data
Constructors and this to initialize and manage objects cleanly
Encapsulation and access modifiers to protect data
Inheritance, base, and overriding to reuse and specialize behavior
Polymorphism to allow flexible runtime behavior
Sealed, abstract classes, and interfaces to control and design your type hierarchies
Mastering these concepts gives you a strong foundation for building robust, maintainable, and scalable .NET applications—and prepares you well for both real-world development and technical interviews.