OOP in C#
Short, interview-ready summary of encapsulation, inheritance, polymorphism, abstraction.
Memory hook
"Encapsulation = hide data, expose behavior; Inheritance = is-a, reuse; Polymorphism = same call, different behavior; Abstraction = contract (interface/abstract class)"
Encapsulation
- Hide fields; expose via properties and methods
- Use private for implementation details; public (or internal) for API
public class Person
{
private int _age;
public int Age
{
get => _age;
set => _age = value > 0 ? value : 0;
}
}
Inheritance (is-a)
public class Animal
{
public virtual void Speak() => Console.WriteLine("...");
}
public class Dog : Animal
{
public override void Speak() => Console.WriteLine("Woof");
}
- Derived gets base members (except private)
- override — replace virtual or abstract method
- sealed — prevent further override
- C#: single inheritance for classes (one base class)
Polymorphism
- Same reference type, different runtime type → call overridden method
Animal a = new Dog();
a.Speak(); // "Woof" (runtime type Dog)
- virtual in base + override in derived = runtime polymorphism
- new on method = hide base method (no override); use with care
Abstraction: interface vs abstract class
| Interface | Abstract class |
|---|---|
| Contract only (no implementation) | Can have implementation + abstract members |
| Multiple per type | Single base class |
| No fields (before C# 8 default impl) | Can have fields, constructors |
| No access modifiers on members (public by default) | Can have protected, etc. |
Interface
public interface IRepository<T>
{
T? Get(int id);
void Save(T entity);
}
public class UserRepo : IRepository<User>
{
public User? Get(int id) => ...;
public void Save(User entity) => ...;
}
Abstract class
public abstract class Shape
{
public abstract double Area();
public virtual string Name => "Shape";
}
public class Circle : Shape
{
public double Radius { get; set; }
public override double Area() => Math.PI * Radius * Radius;
}
override vs new
- override — replaces base implementation; polymorphism applies
- new — hides base member; no polymorphism (call depends on variable type)
Base b = new Derived();
b.Method(); // Base.Method() if Method() was "new"; Derived.Method() if "override"
Interview one-liner
"Encapsulation hides data behind properties and methods. Inheritance reuses and extends a base class; override gives polymorphism. Interfaces define contracts with no implementation; abstract classes can mix abstract and implemented members. Prefer composition over inheritance when is-a doesn’t fit."
Cheat sheet
Encapsulation = private fields, public API
Inheritance = one base class; override for polymorphism
Interface = contract, multiple; abstract class = partial impl, one base
override = polymorphic; new = hide (use carefully)