Lesson 8 of 49 intermediate

Classes & OOP

Organizing Code Into Objects

Open interactive version (quiz + challenge)

Real-world analogy

A class is like a 3D printer mold. The mold defines the shape — every figure that comes out has the same structure (properties) and movable joints (methods). Objects are the printed figures. Change the mold, and every future figure changes. OOP is designing great molds!

What is it?

Classes bundle data (properties) and actions (methods) together. TypeScript adds access modifiers (public/private/protected) to control visibility. Inheritance lets classes extend parent classes. The 4 pillars of OOP are encapsulation, inheritance, polymorphism, and abstraction.

Real-world relevance

NestJS services are classes. React class components are classes. Every enterprise app uses classes to organize business logic!

Key points

Code example

// Simple class
class User {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  greet(): string {
    return `Hi, I'm ${this.name}`;
  }
}

const john = new User("John", 25);
john.greet();  // "Hi, I'm John"

// Shorthand constructor (more common!)
class User {
  constructor(
    public name: string,      // auto-creates this.name
    public age: number,       // auto-creates this.age
    private password: string  // auto-creates this.password (private!)
  ) {}
}

// Access modifiers
class User {
  public name: string;      // anyone can access (default)
  private password: string;  // only User class can access
  protected role: string;    // User + child classes can access
  readonly id: string;       // can READ, cannot CHANGE

  constructor(name: string, password: string) {
    this.id = "auto-generated";
    this.name = name;
    this.password = password;
    this.role = "user";
  }

  private hashPassword(): string {
    return "hashed_" + this.password;
  }
}

const u = new User("John", "secret");
u.name;        // OK — public
// u.password;  // ERROR — private
// u.id = "x";  // ERROR — readonly

// Inheritance
class Animal {
  constructor(public name: string) {}

  speak(): string {
    return `${this.name} makes a sound`;
  }
}

class Dog extends Animal {
  constructor(name: string, public breed: string) {
    super(name);  // call parent constructor
  }

  // Override parent method
  speak(): string {
    return `${this.name} barks!`;
  }
}

const dog = new Dog("Rex", "Labrador");
dog.speak();  // "Rex barks!"

// Implements interface
interface Printable {
  print(): void;
}

class Report implements Printable {
  print(): void {
    console.log("Printing...");
  }
}

// Abstract class
abstract class Shape {
  abstract area(): number;  // child MUST implement

  describe(): string {       // shared method
    return `Area is ${this.area()}`;
  }
}

class Circle extends Shape {
  constructor(private radius: number) {
    super();
  }

  area(): number {
    return Math.PI * this.radius ** 2;
  }
}

// const s = new Shape();     // ERROR — cannot create abstract
const c = new Circle(5);
c.area();       // ~78.54

Line-by-line walkthrough

  1. 1. Simple class
  2. 2. Declaring a class
  3. 3.
  4. 4.
  5. 5.
  6. 6.
  7. 7.
  8. 8.
  9. 9. Closing block
  10. 10.
  11. 11.
  12. 12. Returning a value
  13. 13. Closing block
  14. 14. Closing block
  15. 15.
  16. 16. Declaring a variable
  17. 17.
  18. 18.
  19. 19. Shorthand constructor (more common!)
  20. 20. Declaring a class
  21. 21.
  22. 22.
  23. 23.
  24. 24.
  25. 25.
  26. 26. Closing block
  27. 27.
  28. 28. Access modifiers
  29. 29. Declaring a class
  30. 30.
  31. 31.
  32. 32.
  33. 33.
  34. 34.
  35. 35.
  36. 36.
  37. 37.
  38. 38.
  39. 39.
  40. 40. Closing block
  41. 41.
  42. 42.
  43. 43. Returning a value
  44. 44. Closing block
  45. 45. Closing block
  46. 46.
  47. 47. Declaring a variable
  48. 48.
  49. 49. u.password; // ERROR — private
  50. 50. u.id = "x"; // ERROR — readonly
  51. 51.
  52. 52. Inheritance
  53. 53. Declaring a class
  54. 54.
  55. 55.
  56. 56.
  57. 57. Returning a value
  58. 58. Closing block
  59. 59. Closing block
  60. 60.
  61. 61. Declaring a class
  62. 62.
  63. 63.
  64. 64. Closing block
  65. 65.
  66. 66. Override parent method
  67. 67.
  68. 68. Returning a value
  69. 69. Closing block
  70. 70. Closing block
  71. 71.
  72. 72. Declaring a variable
  73. 73.
  74. 74.
  75. 75. Implements interface
  76. 76. Defining an interface shape
  77. 77.
  78. 78. Closing block
  79. 79.
  80. 80. Declaring a class
  81. 81.
  82. 82. Printing output to the console
  83. 83. Closing block
  84. 84. Closing block
  85. 85.
  86. 86. Abstract class
  87. 87.
  88. 88.
  89. 89.
  90. 90. Grouping related tests together
  91. 91. Returning a value
  92. 92. Closing block
  93. 93. Closing block
  94. 94.
  95. 95. Declaring a class
  96. 96.
  97. 97.
  98. 98. Closing block
  99. 99.
  100. 100.
  101. 101. Returning a value
  102. 102. Closing block
  103. 103. Closing block
  104. 104.
  105. 105. const s = new Shape(); // ERROR — cannot create abstract
  106. 106. Declaring a variable
  107. 107.

Spot the bug

class Dog {
  private name: string;
  constructor(name: string) {
    this.name = name;
  }
}
const dog = new Dog("Rex");
console.log(dog.name);
Need a hint?
Check the access modifier on the name property...
Show answer
The property 'name' is private, so dog.name cannot be accessed outside the class. Fix: change 'private' to 'public', or add a public getName() method.

Explain like I'm 5

A class is like a cookie cutter. The cookie cutter (class) is the shape, and each cookie you make (object) looks the same but can have different sprinkles. You design the cutter once, then stamp out as many cookies as you want!

Fun fact

The 4 Pillars of OOP: Encapsulation (hiding details), Inheritance (extending classes), Polymorphism (same method, different behavior), Abstraction (simplifying complexity). Master these and you master OOP!

Hands-on challenge

Create a class hierarchy: Animal (with speak method), then Dog and Cat that override it. Create instances and call speak on each!

More resources

Open interactive version (quiz + challenge) ← Back to course: Full-Stack Playbook