OOPS concepts

  • Abstraction and Encapsulation compliment each other.
    • Abstraction = Hides implementation (focus on what)
    • Encapsulation = Hides data (focus on how)
    • Abstraction
      • Focuses on what an object does. Only expose what’s necessary
      • Achieved using abstract classes and interfaces.
      • Hiding implementation details and showing only the essential features of an object.
    • Encapsulation
      • protect data integrity and enforce controlled access.
      • Achieved using access modifiers (private, protected, public) and classes.
      • Wrapping up data (variables) and methods (functions) into a single unit (class), with controlled access.
  • Relationships - UML quick course
    • “Is a” (Parent child) - inheritance ”:” + override
    • “Has a” Association - two types:
      • Aggregation : - Has-A (but independent)
        • both objects can survive without each other. Weak association
        • Me and my shirt. A Department has Teachers. Even if the Department is deleted, the Teacher objects can still exist elsewhere.
        • “A diamond”
      • Composition: Has-A (but dependent, ownership)
        • same life-time. Can’t survive without each other. Strong association.
        • Me and my heart. A House has Rooms. If the House is destroyed, the Rooms cannot exist independently.
        • “Colored diamond”.
  • Polymorphism:
    • It allows a single interface (method, operator, or object) to represent different underlying forms (implementations).

    • Static polymorphism - compile time

      • Method Overloading or Operator Overloading.

      • The method call is resolved at compile time.

      • Example: Same method name but different parameter lists.

        class MathUtils
        {
            // Overloading: same method name, different signatures
            public int Add(int a, int b) => a + b;
            public double Add(double a, double b) => a + b;
        }
        var math = new MathUtils();
        Console.WriteLine(math.Add(5, 10));       // calls int version
        Console.WriteLine(math.Add(5.5, 2.3));    // calls double version
         
    • Dynamic polymorphism - run time

      • Method Overriding.
      • The method call is resolved at runtime (depending on the object’s actual type).
      • Requires inheritance/Interface and the virtual/override keywords in C#.
		class Animal
		{
		    public virtual void Speak()
		    {
		        Console.WriteLine("Animal makes a sound");
		    }
		}
 
		class Dog : Animal
		{
		    public override void Speak()
		    {
		        Console.WriteLine("Dog barks");
		    }
		}
 
		class Cat : Animal
		{
		    public override void Speak()
		    {
		        Console.WriteLine("Cat meows");
		    }
		}
 
		Animal a1 = new Dog();
		Animal a2 = new Cat();
 
		a1.Speak(); // Dog barks
		a2.Speak(); // Cat meows
 
 
  • Interface
    • An Interface is a contract that defines what methods, properties, events, or indexers a class or struct must implement — but not how.
    • it’s 100% abstraction: only signatures, no implementation.
    • Promotes loose coupling and dependency injection.
  • Abstract class - code reusability
    • An Abstract Class is a class that cannot be instantiated directly and is meant to be a base class. It can contain:
    • Abstract members → only declarations (no body, must be overridden in child classes).
    • Non-abstract members → with full implementation.
    • A derived class must implement all abstract methods.
    • Supports inheritance (a class can extend only one abstract class). 👉 Think of it as a blueprint: it provides a template but leaves some details to be filled in by subclasses.

🔑 Abstract vs Virtual vs Normal Methods in C#

1. Abstract Methods

  • Declared with abstract keyword inside an abstract class.
  • No implementation in base class.
  • Must be overridden in derived class.
  • Enforces a contract for child classes.
abstract class Vehicle
{
    public abstract void Drive();  // No body
}
 
class Car : Vehicle
{
    public override void Drive()   // Must implement
    {
        Console.WriteLine("Car drives...");
    }
}

2. Virtual Methods

  • Declared with virtual keyword.
  • Have a default implementation in base class.
  • Child class can optionally override.
  • Supports runtime polymorphism.
abstract class Vehicle
{
    public virtual void Honk()   // Default implementation
    {
        Console.WriteLine("Beep Beep!");
    }
}
 
class Bike : Vehicle
{
    public override void Honk()   // Optional override
    {
        Console.WriteLine("Bike says: Beeeep!");
    }
}

3. Normal Methods (Non-Virtual)

  • Declared normally (no abstract / virtual).
  • Cannot be overridden.
  • Child can only hide it using new keyword.
  • Not true polymorphism — behavior depends on reference type.
  • “new” when using Vehicle v = new Car(), it still calls the base class Honk(), not the child’s.
abstract class Vehicle
{
    public void Honk()   // Normal method
    {
        Console.WriteLine("Beep Beep!");
    }
}
 
class Car : Vehicle
{
    public new void Honk()   // Method hiding
    {
        Console.WriteLine("Car says: Honk Honk!");
    }
}

Comparison Table

FeatureAbstractVirtualNormal
KeywordabstractvirtualNone
Implementation in Base❌ No body✅ Default body✅ Body
Must Override?✅ Yes❌ No (optional)❌ Not allowed
Supports Polymorphism✅ Yes (runtime)✅ Yes (runtime)❌ No (only hiding with new)
UsageEnforce contractProvide default, allow overridePrevent overriding

👉 Quick Rule of Thumb

  • Use abstract when you must force subclasses to implement.
  • Use virtual when you want a default, but allow customization.
  • Use normal when you want to lock down behavior.

Great question 👍 This is a classic interview topic. Let’s break it down clearly.


🔑 Difference Between Interface and Abstract Class (C# context)

AspectInterfaceAbstract Class
PurposeDefines a contract (what should be done).Serves as a base class (can provide partial implementation + enforce rules).
ImplementationCannot have implementation (until C# 8.0, which allows default methods).Can have both abstract (no body) and concrete (with body) methods.
InstantiationCannot be instantiated.Cannot be instantiated.
MembersCan declare methods, properties, events, indexers. No fields.Can have fields, properties, methods, constructors, etc.
Access ModifiersAll members are public by default.Members can have different access modifiers (public, protected, private).
InheritanceA class can implement multiple interfaces (supports multiple inheritance).A class can inherit only one abstract class (single inheritance).
When to UseWhen unrelated classes must follow the same contract.When classes share a common base and some shared logic.
Keywordinterfaceabstract class
PolymorphismAchieved via implementation in multiple classes.Achieved via inheritance and overriding.
ConstructorsNot allowed.Allowed (but cannot be used directly to instantiate).

Example: Interface

public interface IPayment
{
    void Pay(decimal amount);   // no body
}
 
public class CreditCardPayment : IPayment
{
    public void Pay(decimal amount)
    {
        Console.WriteLine($"Paid {amount} by Credit Card.");
    }
}

Example: Abstract Class

public abstract class Payment
{
    public abstract void ProcessPayment(decimal amount);  // must override
 
    public void ShowConfirmation()
    {
        Console.WriteLine("Payment processed successfully!");
    }
}
 
public class PayPalPayment : Payment
{
    public override void ProcessPayment(decimal amount)
    {
        Console.WriteLine($"Paid {amount} using PayPal.");
    }
}

Rule of Thumb

  • Use Interface → when you just want to define what must be done across unrelated classes.
  • Use Abstract Class → when you want to enforce some behavior + some shared code across related classes.

👉 In short:

  • Interface = 100% abstraction, multiple inheritance allowed.
  • Abstract Class = partial abstraction, single inheritance, can share common code.

Would you like me to also make a quick real-life analogy table (like Interface = contract, Abstract = blueprint) so it’s easier to memorize in interviews?


👍 In .NET Framework / .NET Core, both abstract classes and interfaces are used widely in the Base Class Library (BCL).

Here are some famous examples you should remember for interviews 👇

🔑 Famous Abstract Classes in .NET

These provide base functionality + some shared implementation (reusability).

Abstract ClassNamespaceUsage
StreamSystem.IOBase for file, memory, network streams (FileStream, MemoryStream, NetworkStream).
DbConnectionSystem.Data.CommonBase for database connections (SqlConnection, OracleConnection, NpgsqlConnection).
DbCommandSystem.Data.CommonBase for executing database commands (SqlCommand, OracleCommand).
WebRequestSystem.NetBase for network requests (HttpWebRequest, FtpWebRequest).
XmlReader / XmlWriterSystem.XmlBase for reading/writing XML.
TaskSchedulerSystem.Threading.TasksBase for scheduling tasks.

👉 These classes provide reusable methods (e.g., Stream.Read()) and leave others abstract (must be implemented).


🔑 Famous Interfaces in .NET

These define contracts (flexibility, multiple implementations possible).

InterfaceNamespaceUsage
IDisposableSystemEnsures cleanup of resources (using statement).
IEnumerable / IEnumerable<T>System.Collections / System.Collections.GenericEnables foreach iteration.
ICollection<T> / IList<T>System.Collections.GenericDefines collection contracts.
IComparable<T>SystemDefines sorting rules (List<T>.Sort()).
IEquatable<T>SystemDefines custom equality logic.
IAsyncDisposableSystemAsynchronous resource cleanup (await using).
ILoggerMicrosoft.Extensions.LoggingDefines logging contract for DI.

👉 Interfaces let you plug and play different implementations (e.g., ILogger → ConsoleLogger, FileLogger, ApplicationInsightsLogger).


✅ Quick Takeaway

  • Abstract Classes in .NET → Stream, DbConnection, WebRequest → promote code reuse.
  • Interfaces in .NET → IDisposable, IEnumerable, ILogger → promote flexibility & consistency.