OOPS Concepts
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".
- Aggregation : - Has-A (but independent)
- 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
abstractkeyword 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
virtualkeyword. - 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
newkeyword. - 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
| Feature | Abstract | Virtual | Normal |
|---|---|---|---|
| Keyword | abstract |
virtual |
None |
| 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) |
| Usage | Enforce contract | Provide default, allow override | Prevent 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)
| Aspect | Interface | Abstract Class |
|---|---|---|
| Purpose | Defines a contract (what should be done). | Serves as a base class (can provide partial implementation + enforce rules). |
| Implementation | Cannot have implementation (until C# 8.0, which allows default methods). | Can have both abstract (no body) and concrete (with body) methods. |
| Instantiation | Cannot be instantiated. | Cannot be instantiated. |
| Members | Can declare methods, properties, events, indexers. No fields. | Can have fields, properties, methods, constructors, etc. |
| Access Modifiers | All members are public by default. | Members can have different access modifiers (public, protected, private). |
| Inheritance | A class can implement multiple interfaces (supports multiple inheritance). | A class can inherit only one abstract class (single inheritance). |
| When to Use | When unrelated classes must follow the same contract. | When classes share a common base and some shared logic. |
| Keyword | interface |
abstract class |
| Polymorphism | Achieved via implementation in multiple classes. | Achieved via inheritance and overriding. |
| Constructors | Not 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 Class | Namespace | Usage |
|---|---|---|
Stream |
System.IO |
Base for file, memory, network streams (FileStream, MemoryStream, NetworkStream). |
DbConnection |
System.Data.Common |
Base for database connections (SqlConnection, OracleConnection, NpgsqlConnection). |
DbCommand |
System.Data.Common |
Base for executing database commands (SqlCommand, OracleCommand). |
WebRequest |
System.Net |
Base for network requests (HttpWebRequest, FtpWebRequest). |
XmlReader / XmlWriter |
System.Xml |
Base for reading/writing XML. |
TaskScheduler |
System.Threading.Tasks |
Base 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).
| Interface | Namespace | Usage |
|---|---|---|
IDisposable |
System |
Ensures cleanup of resources (using statement). |
IEnumerable / IEnumerable<T> |
System.Collections / System.Collections.Generic |
Enables foreach iteration. |
ICollection<T> / IList<T> |
System.Collections.Generic |
Defines collection contracts. |
IComparable<T> |
System |
Defines sorting rules (List<T>.Sort()). |
IEquatable<T> |
System |
Defines custom equality logic. |
IAsyncDisposable |
System |
Asynchronous resource cleanup (await using). |
ILogger |
Microsoft.Extensions.Logging |
Defines 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.