Fundamentals track

OOP Concepts Tutorial

Classes, objects, the four pillars, SOLID and design patterns — explained with JavaScript and C# side by side.

BeginnerExamples use modern JavaScript (ES2022 private fields) and C# 13.
0/38 complete
Topics
38
Full lessons
38
Est. hours
~7
Interview Qs
29

Overview

Object-oriented programming (OOP) organises code around objects: bundles of data (state) and the behaviour that works on that data. Most languages you will use professionally — C#, Java, TypeScript, JavaScript, Python — support it.

This track teaches the concepts once, language-neutrally, then shows them in JavaScript (runnable right here) and C#. It ends with SOLID principles and the design patterns interviewers ask about most.

What you will learn

  • Model real-world problems with classes and objects
  • Apply encapsulation, abstraction, inheritance and polymorphism
  • Choose between abstract classes, interfaces and composition
  • Write maintainable code with SOLID and common design patterns

Prerequisites

None — this track starts from the very beginning.

Learning path

The recommended sequence, from beginner to advanced. Each stage builds on the one before.

  1. 1Foundations · 8 topics · Beginner
    Introduction to OOP · Procedural vs Object-Oriented · Classes and Objects · Constructors · Fields, Properties and Methods · Access Modifiers · Static Members · The this Keyword
  2. 2The Four Pillars · 4 topics · Beginner
    Encapsulation · Abstraction · Inheritance · Polymorphism
  3. 3Polymorphism in Depth · 6 topics · Beginner → Intermediate
    Method Overloading · Method Overriding · Virtual and Abstract Methods · Abstract Classes · Interfaces · Abstract Class vs Interface
  4. 4Object Relationships · 3 topics · Intermediate
    Association, Aggregation and Composition · Composition over Inheritance · Dependency Injection Basics
  5. 5Design Principles · 6 topics · Intermediate
    SOLID Principles · Single Responsibility Principle · Open/Closed Principle · Liskov Substitution Principle · Interface Segregation Principle · Dependency Inversion Principle
  6. 6Design Patterns · 6 topics · Intermediate → Advanced
    Design Patterns Overview · Singleton Pattern · Factory Pattern · Strategy Pattern · Observer Pattern · Repository Pattern
  7. 7Practice · 5 topics · Advanced
    OOP in JavaScript · OOP in C# · UML Class Diagrams · OOP Practice Project · OOP Interview Questions

Complete topic list

38 topics
1

Foundations

8 topics
  1. Introduction to OOPBeginner6m
  2. Procedural vs Object-OrientedBeginner5m
  3. Classes and ObjectsBeginner5m
  4. ConstructorsBeginner6m
  5. Fields, Properties and MethodsBeginner5m
  6. Access ModifiersBeginner5m
  7. Static MembersBeginner5m
  8. The this KeywordBeginner5m
2

The Four Pillars

4 topics
  1. EncapsulationBeginner5m
  2. AbstractionBeginner6m
  3. InheritanceBeginner5m
  4. PolymorphismBeginner5m
3

Polymorphism in Depth

6 topics
  1. Method OverloadingBeginner5m
  2. Method OverridingBeginner5m
  3. Virtual and Abstract MethodsBeginner6m
  4. Abstract ClassesBeginner6m
  5. InterfacesBeginner5m
  6. Abstract Class vs InterfaceIntermediate6m
4

Object Relationships

3 topics
  1. Association, Aggregation and CompositionIntermediate6m
  2. Composition over InheritanceIntermediate6m
  3. Dependency Injection BasicsIntermediate5m
5

Design Principles

6 topics
  1. SOLID PrinciplesIntermediate6m
  2. Single Responsibility PrincipleIntermediate5m
  3. Open/Closed PrincipleIntermediate5m
  4. Liskov Substitution PrincipleIntermediate6m
  5. Interface Segregation PrincipleIntermediate5m
  6. Dependency Inversion PrincipleIntermediate5m
6

Design Patterns

6 topics
  1. Design Patterns OverviewIntermediate6m
  2. Singleton PatternIntermediate5m
  3. Factory PatternIntermediate5m
  4. Strategy PatternAdvanced5m
  5. Observer PatternAdvanced5m
  6. Repository PatternAdvanced5m
7

Practice

5 topics
  1. OOP in JavaScriptAdvanced6m
  2. OOP in C#Advanced6m
  3. UML Class DiagramsAdvanced5m
  4. OOP Practice ProjectAdvanced7m
  5. OOP Interview QuestionsAdvanced15m

Visual guides

2 diagrams

Code example

A taste of the track, from Introduction to OOP.

JavaScriptA tiny library modelled as objects Runnable
class Book {
  constructor(title, author) {
    this.title = title;        // state
    this.author = author;
    this.isBorrowed = false;
  }


  borrow() {                   // behaviour
    if (this.isBorrowed) return `${this.title} is already borrowed`;
    this.isBorrowed = true;
    return `You borrowed ${this.title}`;
  }
}


const book1 = new Book('Wings of Fire', 'A. P. J. Abdul Kalam');
const book2 = new Book('The Guide', 'R. K. Narayan');


console.log(book1.borrow());
console.log(book1.borrow());
console.log(book2.isBorrowed);
console.log(book1);
Expected output
You borrowed Wings of Fire
Wings of Fire is already borrowed
false
{ title: 'Wings of Fire', author: 'A. P. J. Abdul Kalam', isBorrowed: true }
Opens this example in the full playground

Practice exercises

Show all 37 exercises
Static Members

Create a Temperature class with a static method fromFahrenheit(f) that returns a new Temperature in Celsius, and a static constant FREEZING = 0.

The this Keyword

Create a QueryBuilder class with where(field), orderBy(field) and build() methods. where and orderBy store their values and return this, so you can write new QueryBuilder().where("age").orderBy("name").build().

Encapsulation

Create a Temperature class with a private #celsius field. Add a celsius getter, a celsius setter that rejects values below -273.15, and a fahrenheit getter.

Abstraction

Write a TypeScript interface Shape with area(): number, and two classes Circle and Rectangle that implement it. Write a function totalArea(shapes: Shape[]).

Inheritance

Create a Shape base class with a name and an area() method returning 0. Create Circle and Square subclasses that override area(). Log the area of each.

Polymorphism

Create Notification classes — Email, Sms and Push — each with a send(message) method that returns a different string. Send the same message through all three in a loop.

Method Overloading

Write a JavaScript function area(a, b) that returns the area of a square when called with one number and of a rectangle when called with two.

Method Overriding

Create a Shape class with describe() returning "A shape", and a Circle subclass whose describe() returns the parent text plus " that is round". Use super.

Virtual and Abstract Methods

Create a base class Animal with a "virtual" describe() that returns "<name> is an animal" and an "abstract" sound() that throws. Create Dog with sound() returning "Woof", then log both methods.

Abstract Classes

Create an abstract Account class with a balance and an abstract interestRate(). Create SavingsAccount (4%) and FixedDeposit (7%), and a shared method yearlyInterest() = balance × rate / 100.

Interfaces

Define a Logger “interface” with one method log(message). Implement ConsoleLogger (returns "console: msg") and MemoryLogger (stores messages in an array). Write a function process(logger) that logs "started" and works with both.

Abstract Class vs Interface

Model a Bird (abstract class with name and a shared describe()) and a Flyer capability (fly()). Create Sparrow (bird + flyer), Penguin (bird only) and Drone (flyer only, not a bird). Log which of the three can fly.

Association, Aggregation and Composition

Create a Playlist that aggregates Song objects (songs exist independently) and a Song that is composed of a private Lyrics object it creates itself. Log the playlist length and the first line of a song’s lyrics.

Composition over Inheritance

Build a Character that has a weapon part. Create Sword (attack returns "slashes for 10") and Bow (attack returns "shoots for 7"). Make a character, attack, switch weapon, attack again.

Dependency Injection Basics

Write a Greeter class that receives a clock object with a getHour() method. greet() returns "Good morning" before 12 and "Good afternoon" otherwise. Test it with two fake clocks.

SOLID Principles

Identify which SOLID principle each smell violates: (1) a PaymentProcessor with a switch on payment type that grows every month; (2) an IWorker interface with Work() and Eat() that robots must implement; (3) a ReportService that creates new SqlConnection() inside its methods.

Single Responsibility Principle

This class does two jobs: class Report { constructor(data) { this.data = data; } average() { ... } toCsv() { ... } }. Split it into Report (average) and ReportCsvFormatter (toCsv), then use both.

Open/Closed Principle

Make shipping cost extensible: create StandardShipping (₹50) and ExpressShipping (₹150), each with cost(). Write a function orderTotal(amount, shipping) that never needs editing when a new shipping type appears. Then add FreeShipping.

Liskov Substitution Principle

Bird has fly(). Penguin extends Bird and throws in fly() — an LSP violation. Redesign with a Bird base (eat()) and a separate FlyingBird subclass (fly()), so Penguin never promises to fly.

Interface Segregation Principle

A Worker contract has work() and eat(). A Robot can work but not eat. Split it into Workable and Eatable roles, implement Human (both) and Robot (work only), and run a shift that calls work() on everyone who can work.

Dependency Inversion Principle

Write a PriceService that depends on a rateProvider with getRate(currency). It converts an INR amount into another currency. Use a FixedRateProvider ({ USD: 0.012 }) for a quick test.

Design Patterns Overview

Write a tiny Decorator (structural pattern): a function withTimestamp(logger) that returns a new logger whose log(msg) adds "2026-10-28 " in front of the original logger’s output.

Singleton Pattern

Create a Logger singleton with a static getInstance() method and a log(msg) method that stores messages in an array. Log from two “different places” and show both messages are in the same logger.

Factory Pattern

Create a ShapeFactory.create(type, size) that returns a Circle or Square object with an area() method. Create one of each and log their areas (round the circle to 2 decimals).

Strategy Pattern

Create a TextFormatter that uses a strategy to format a string: UpperCaseStrategy, LowerCaseStrategy and TitleCaseStrategy. Format "hello oop world" with each.

Observer Pattern

Create a NewsChannel subject with subscribe(fn) and publish(headline). Subscribe two readers that log "Asha read: …" and "Ravi read: …", publish one headline, unsubscribe Ravi, and publish another.

Repository Pattern

Write a UserRepository (in memory) with add(user), findByEmail(email) and count(). Add two users and look one up by email, ignoring case.

OOP in JavaScript

Write a Serializable mixin that adds toJSONString() (returns JSON.stringify(this)) to any class. Apply it to a Product class with name and price and log the result.

OOP in C#

Add a FixedDepositAccount (sealed) that never allows withdrawals and pays 7% interest via IInterestBearing. Create one with 10000, try to withdraw 100 and print the interest.

UML Class Diagrams

Write a Mermaid class diagram for: a Library has many Books (books can exist without the library); a Member borrows 0..5 Books; StudentMember and StaffMember inherit from Member.

OOP Practice Project

Extend the system without editing any existing class: add a PremiumMember (limit 10) and a NoFine strategy (always 0). Borrow three books with a premium member, return one 10 days late with NoFine, and log the fine.

Common interview questions

Frequently asked questions

Is JavaScript object-oriented?
Yes. JavaScript is multi-paradigm: it supports OOP through prototypes, and the class syntax (ES2015) is a clearer way to write prototype-based code. It also supports functional programming.
Do I need OOP for web development?
You will meet it constantly: ASP.NET Core, Angular, NestJS and most backend frameworks are built around classes, interfaces and dependency injection. Understanding OOP makes these frameworks far easier to learn.
Should I learn OOP before or after a language?
Learn the basics of one language first (variables, functions, loops), then OOP. This track uses JavaScript and C#, so the JavaScript or C# fundamentals are enough.