C#  

C# .NET Object-Oriented Programming – A Complete Guide (Beginner to Advanced)

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:

  1. Identity

  2. Variables

  3. 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:

  • Takes input (parameters)

  • Performs operations

  • Returns output (optional)

int Add(int a, int b)
{
    int c = a + b;
    return c;
}

Here:

  • Add is the method name.

  • a and b are parameters.

  • c is a local variable.

  • return c; sends the result back.

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:

  1. Encapsulation: binding data and methods together

  2. Inheritance: reusing members of one class in another

  3. Abstraction: hiding implementation details, exposing only necessary features

  4. 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:

  1. Static variables: shared across all objects

  2. Instance variables: unique per object

  3. Method parameters: input to methods

  4. 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

  • Declared inside a class but without static.

  • Each object gets its own copy.

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

  • Method parameters: passed into a method and used only inside that method.

  • Local variables: declared inside the method body; exist only within that method.

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:

  • Whether they take arguments

  • Whether they return a value

Examples

  1. No arguments, no return value

  2. With arguments, no return value

  3. With arguments, with a return value

  4. No arguments, with return value

C# also distinguishes between:

  • Static methods – accessed via class name

  • Instance methods – accessed via object reference

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:

  • Has the same name as the class

  • Has no return type

  • Runs automatically when an object is created

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:

  • Refer to instance variables

  • Avoid naming conflicts between parameters and fields

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:

  • Class → public

  • Variables → private

  • Methods (getters/setters) → public

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:

  • Parent/Base class – the class whose members are reused

  • Child/Derived class – the class that inherits members

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

  • Reference to the current object

  • Used in methods and constructors

this()

  • Used to call another constructor in the same class (constructor chaining)

base

  • Reference to the parent class from a child class

  • Used to access parent class members

base()

  • Used in a child constructor to explicitly call the parent constructor

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

  • Base class method must be marked virtual.

  • Child class method must be marked override.

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:

  1. Compile-time polymorphism – Method Overloading

  2. 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()
    }
}
  • Upcasting: storing a child object in a parent reference.

  • Behavior is decided at runtime.

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:

  • Is marked with abstract

  • Can contain both concrete methods (with body) and abstract methods (no body).

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.