+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Part 35 of 355

๐Ÿ“ž Super Keyword: Calling Parent Class Members

Master the super keyword in TypeScript to access parent class methods and constructors with practical examples ๐Ÿš€

๐Ÿš€Intermediate
20 min read

Prerequisites

  • Class inheritance basics ๐Ÿ—๏ธ
  • Constructor understanding ๐Ÿ”ง
  • Method definitions ๐Ÿ“

What you'll learn

  • Understand super keyword fundamentals ๐ŸŽฏ
  • Call parent constructors properly โšก
  • Access parent methods effectively ๐Ÿ“ž
  • Handle method overriding scenarios ๐Ÿ”„

๐ŸŽฏ Introduction

Welcome to the super-powered world of the super keyword! ๐ŸŽ‰ In this guide, weโ€™ll explore one of the most important tools for working with inheritance in TypeScript: the ability to communicate with parent classes.

Youโ€™ll discover how super acts like a bridge ๐ŸŒ‰ between child and parent classes, allowing you to access parent constructors and methods. Whether youโ€™re building complex class hierarchies ๐Ÿ—๏ธ or extending existing functionality ๐Ÿ”ง, understanding super is essential for writing clean, maintainable code.

By the end of this tutorial, youโ€™ll be a super expert at using super! Letโ€™s dive in! ๐ŸŠโ€โ™‚๏ธ

๐Ÿ“š Understanding the Super Keyword

๐Ÿค” What is Super?

The super keyword is like a telephone ๐Ÿ“ž that lets you call your parent class directly. Think of it as a way to say โ€œHey parent, I need to use your functionality!โ€

In TypeScript terms, super allows you to:

  • โœจ Call the parent class constructor
  • ๐Ÿš€ Access parent class methods
  • ๐Ÿ›ก๏ธ Extend parent functionality without losing it
  • ๐Ÿ”ง Coordinate between parent and child classes

๐Ÿ’ก Why Use Super?

Hereโ€™s why developers love the super keyword:

  1. Code Reuse โ™ป๏ธ: Donโ€™t rewrite what already works
  2. Proper Initialization ๐ŸŽฏ: Ensure parent setup happens first
  3. Method Enhancement ๐Ÿš€: Extend rather than replace functionality
  4. Clean Architecture ๐Ÿ—๏ธ: Maintain clear class relationships

Real-world example: Imagine building a notification system ๐Ÿ“ฑ. Your base Notification class handles basic setup, while EmailNotification uses super() to initialize the base, then adds email-specific features.

๐Ÿ”ง Basic Syntax and Usage

๐Ÿ“ Constructor Super Calls

Letโ€™s start with the most common use of super:

// ๐Ÿ‘ค Base person class
class Person {
  name: string;
  age: number;
  id: string;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
    this.id = Math.random().toString(36).substring(2, 9); // ๐ŸŽฒ Random ID
    console.log(`๐Ÿ‘ค Person created: ${this.name} (ID: ${this.id})`);
  }

  // ๐Ÿ‘‹ Basic greeting
  greet(): string {
    return `Hello, I'm ${this.name}! ๐Ÿ˜Š`;
  }

  // ๐Ÿ“„ Get basic info
  getInfo(): string {
    return `${this.name}, age ${this.age} (ID: ${this.id})`;
  }
}

// ๐Ÿ‘จโ€๐Ÿ’ผ Employee extends Person
class Employee extends Person {
  jobTitle: string;
  salary: number;

  constructor(name: string, age: number, jobTitle: string, salary: number) {
    // ๐Ÿ“ž MUST call parent constructor first!
    super(name, age); // This initializes name, age, and id
    
    // โœจ Now we can add our own properties
    this.jobTitle = jobTitle;
    this.salary = salary;
    console.log(`๐Ÿ‘จโ€๐Ÿ’ผ Employee specialized: ${jobTitle}`);
  }

  // ๐Ÿ’ผ Employee-specific method
  work(): string {
    return `${this.name} is working as a ${this.jobTitle}! ๐Ÿ’ผ`;
  }

  // ๐Ÿ“Š Get complete employee info
  getInfo(): string {
    // ๐Ÿ“ž Call parent's getInfo, then add our own details
    const parentInfo = super.getInfo(); // Gets basic person info
    return `${parentInfo} - ${this.jobTitle} ($${this.salary.toLocaleString()})`;
  }
}

// ๐ŸŽฎ Let's see it in action!
const employee = new Employee("Alice", 30, "Senior Developer", 95000);
console.log(employee.greet()); // "Hello, I'm Alice! ๐Ÿ˜Š" (inherited)
console.log(employee.work()); // "Alice is working as a Senior Developer! ๐Ÿ’ผ"
console.log(employee.getInfo()); // Combined parent + child info

๐Ÿ’ก Explanation: Notice how super(name, age) in the constructor calls the parent constructor, and super.getInfo() calls the parent method!

๐ŸŽฏ Method Enhancement Pattern

Hereโ€™s how to enhance parent functionality without losing it:

// ๐Ÿฆ Bank account base class
class BankAccount {
  protected balance: number;
  protected accountNumber: string;

  constructor(accountNumber: string, initialBalance: number = 0) {
    this.accountNumber = accountNumber;
    this.balance = initialBalance;
    console.log(`๐Ÿฆ Account ${accountNumber} created with $${initialBalance}`);
  }

  // ๐Ÿ’ฐ Basic deposit
  deposit(amount: number): void {
    if (amount > 0) {
      this.balance += amount;
      console.log(`โœ… Deposited $${amount}. New balance: $${this.balance}`);
    } else {
      console.log("โŒ Deposit amount must be positive");
    }
  }

  // ๐Ÿ’ธ Basic withdrawal
  withdraw(amount: number): boolean {
    if (amount > 0 && amount <= this.balance) {
      this.balance -= amount;
      console.log(`โœ… Withdrew $${amount}. New balance: $${this.balance}`);
      return true;
    } else {
      console.log("โŒ Invalid withdrawal amount");
      return false;
    }
  }

  // ๐Ÿ“Š Check balance
  getBalance(): number {
    return this.balance;
  }
}

// ๐Ÿ’ณ Premium account with enhanced features
class PremiumAccount extends BankAccount {
  private rewardPoints: number = 0;
  private bonusRate: number = 0.02; // 2% bonus

  constructor(accountNumber: string, initialBalance: number = 0) {
    super(accountNumber, initialBalance); // ๐Ÿ“ž Call parent constructor
    console.log("โœจ Premium features activated!");
  }

  // ๐Ÿš€ Enhanced deposit with rewards
  deposit(amount: number): void {
    // ๐Ÿ“ž First, do the normal deposit
    super.deposit(amount);
    
    // โœจ Then add premium features
    if (amount > 0) {
      const bonusPoints = Math.floor(amount * this.bonusRate);
      this.rewardPoints += bonusPoints;
      console.log(`๐ŸŒŸ Earned ${bonusPoints} reward points! Total: ${this.rewardPoints}`);
    }
  }

  // ๐Ÿ’Ž Enhanced withdrawal with premium benefits
  withdraw(amount: number): boolean {
    // ๐Ÿ“ž Try the normal withdrawal first
    const success = super.withdraw(amount);
    
    // โœจ Add premium features if successful
    if (success && amount >= 100) {
      console.log("๐ŸŽ Large withdrawal bonus: +5 reward points!");
      this.rewardPoints += 5;
    }
    
    return success;
  }

  // ๐Ÿ† Premium-specific method
  getRewardPoints(): number {
    return this.rewardPoints;
  }

  // ๐ŸŽฏ Redeem points for cash
  redeemPoints(): void {
    if (this.rewardPoints >= 100) {
      const cashValue = Math.floor(this.rewardPoints / 100) * 10; // $10 per 100 points
      this.rewardPoints %= 100; // Keep remainder
      
      // ๐Ÿ“ž Use parent's deposit method to add the cash
      super.deposit(cashValue);
      console.log(`๐ŸŽ‰ Redeemed points for $${cashValue}!`);
    } else {
      console.log("โŒ Need at least 100 points to redeem");
    }
  }
}

// ๐Ÿ’ณ Let's test premium features!
const premiumAccount = new PremiumAccount("PREM001", 1000);
premiumAccount.deposit(500); // Earns reward points!
premiumAccount.withdraw(200); // Earns bonus points!
console.log(`๐Ÿ’ฐ Balance: $${premiumAccount.getBalance()}`);
console.log(`๐ŸŒŸ Reward Points: ${premiumAccount.getRewardPoints()}`);

๐Ÿ’ก Practical Examples

๐ŸŽฎ Example 1: Game Character Evolution

Letโ€™s create a game where characters can evolve and gain new abilities:

// ๐Ÿ—ก๏ธ Base warrior class
class Warrior {
  name: string;
  health: number;
  strength: number;
  level: number;

  constructor(name: string) {
    this.name = name;
    this.health = 100;
    this.strength = 15;
    this.level = 1;
    console.log(`โš”๏ธ ${name} becomes a warrior!`);
  }

  // โš”๏ธ Basic attack
  attack(): number {
    const damage = this.strength + Math.floor(Math.random() * 10);
    console.log(`โš”๏ธ ${this.name} attacks for ${damage} damage!`);
    return damage;
  }

  // ๐Ÿ›ก๏ธ Defend action
  defend(): void {
    console.log(`๐Ÿ›ก๏ธ ${this.name} raises their shield!`);
  }

  // ๐Ÿ“ˆ Level up
  levelUp(): void {
    this.level++;
    this.health += 20;
    this.strength += 3;
    console.log(`๐ŸŽ‰ ${this.name} reached level ${this.level}!`);
  }

  // ๐Ÿ“Š Get stats
  getStats(): string {
    return `โš”๏ธ ${this.name} - Level ${this.level} | HP: ${this.health} | STR: ${this.strength}`;
  }
}

// ๐Ÿฐ Paladin - evolved warrior with holy powers
class Paladin extends Warrior {
  holyPower: number;
  healingAbility: number;

  constructor(name: string) {
    // ๐Ÿ“ž First become a warrior
    super(name);
    
    // โœจ Then gain holy powers
    this.holyPower = 25;
    this.healingAbility = 15;
    console.log(`โœจ ${name} is blessed with holy power!`);
  }

  // ๐Ÿš€ Enhanced attack with holy damage
  attack(): number {
    // ๐Ÿ“ž Do the basic warrior attack
    const basicDamage = super.attack();
    
    // โœจ Add holy damage
    const holyDamage = Math.floor(this.holyPower / 5);
    const totalDamage = basicDamage + holyDamage;
    
    if (holyDamage > 0) {
      console.log(`โœจ Holy power adds ${holyDamage} divine damage!`);
    }
    
    return totalDamage;
  }

  // ๐Ÿ›ก๏ธ Enhanced defend with blessing
  defend(): void {
    // ๐Ÿ“ž Do basic defense
    super.defend();
    
    // โœจ Add divine blessing
    console.log(`โœจ Divine blessing protects ${this.name}!`);
    this.heal(5); // Self-heal while defending
  }

  // ๐Ÿ’– Healing ability
  heal(amount: number): void {
    this.health = Math.min(this.health + amount, 100 + (this.level * 20));
    console.log(`๐Ÿ’– ${this.name} heals for ${amount} HP! Current: ${this.health}`);
  }

  // ๐Ÿ“ˆ Enhanced level up with holy power growth
  levelUp(): void {
    // ๐Ÿ“ž Do the basic level up
    super.levelUp();
    
    // โœจ Grow holy powers
    this.holyPower += 5;
    this.healingAbility += 3;
    console.log(`โœจ Holy powers grow stronger! Holy Power: ${this.holyPower}`);
  }

  // ๐Ÿ™ Prayer for team healing
  prayForTeam(): void {
    console.log(`๐Ÿ™ ${this.name} prays for divine intervention!`);
    console.log("โœจ Team receives blessing of protection!");
  }

  // ๐Ÿ“Š Enhanced stats with holy info
  getStats(): string {
    // ๐Ÿ“ž Get basic warrior stats
    const basicStats = super.getStats();
    
    // โœจ Add paladin-specific info
    return `${basicStats} | Holy: ${this.holyPower} | Heal: ${this.healingAbility} โœจ`;
  }
}

// โšก Thunder Knight - ultimate evolution
class ThunderKnight extends Paladin {
  lightningPower: number;
  stormsInvoked: number;

  constructor(name: string) {
    // ๐Ÿ“ž First become a paladin (which calls warrior constructor too!)
    super(name);
    
    // โšก Gain storm powers
    this.lightningPower = 40;
    this.stormsInvoked = 0;
    console.log(`โšก ${name} commands the power of storms!`);
  }

  // โšก Ultimate attack with all powers combined
  attack(): number {
    // ๐Ÿ“ž Get paladin attack (which includes warrior attack + holy damage)
    const combinedDamage = super.attack();
    
    // โšก Add lightning damage
    const lightningDamage = Math.floor(this.lightningPower / 3);
    const finalDamage = combinedDamage + lightningDamage;
    
    console.log(`โšก Lightning strikes for ${lightningDamage} shock damage!`);
    return finalDamage;
  }

  // ๐ŸŒฉ๏ธ Special storm ability
  invokeStorm(): void {
    this.stormsInvoked++;
    console.log(`๐ŸŒฉ๏ธ ${this.name} summons a devastating storm! (Storm #${this.stormsInvoked})`);
    
    // โšก Massive damage attack
    const stormDamage = this.lightningPower * 2;
    console.log(`โšก Storm deals ${stormDamage} area damage!`);
    
    // ๐Ÿ“ž Use parent's heal to recover from the effort
    this.heal(10);
  }

  // ๐Ÿ“ˆ Triple-enhanced level up
  levelUp(): void {
    // ๐Ÿ“ž Do paladin level up (which does warrior level up too!)
    super.levelUp();
    
    // โšก Grow storm powers
    this.lightningPower += 8;
    console.log(`โšก Storm powers intensify! Lightning Power: ${this.lightningPower}`);
  }

  // ๐Ÿ“Š Ultimate stats display
  getStats(): string {
    // ๐Ÿ“ž Get paladin stats (which includes warrior stats)
    const inheritedStats = super.getStats();
    
    // โšก Add thunder knight info
    return `${inheritedStats} | Lightning: ${this.lightningPower} | Storms: ${this.stormsInvoked} โšก`;
  }
}

// ๐ŸŽฎ Let's witness the evolution!
const hero = new ThunderKnight("Thorgar");

console.log("\n" + hero.getStats());
hero.attack(); // Combines all three attack types!
hero.defend(); // Enhanced defense with healing
hero.invokeStorm(); // Unique storm ability
hero.levelUp(); // Triple-enhanced leveling
console.log("\n" + hero.getStats());

๐Ÿช Example 2: E-commerce Notification System

Letโ€™s build a notification system that builds upon base functionality:

// ๐Ÿ“จ Base notification class
class Notification {
  id: string;
  message: string;
  timestamp: Date;
  priority: 'low' | 'medium' | 'high';
  sent: boolean = false;

  constructor(message: string, priority: 'low' | 'medium' | 'high' = 'medium') {
    this.id = `notif_${Date.now()}_${Math.random().toString(36).substr(2, 5)}`;
    this.message = message;
    this.priority = priority;
    this.timestamp = new Date();
    console.log(`๐Ÿ“จ Notification created: ${this.id}`);
  }

  // ๐Ÿ“ค Basic send method
  send(): boolean {
    if (this.sent) {
      console.log("โš ๏ธ Notification already sent");
      return false;
    }

    this.sent = true;
    console.log(`๐Ÿ“ค Notification sent: "${this.message}"`);
    return true;
  }

  // ๐Ÿ“‹ Get notification details
  getDetails(): string {
    return `๐Ÿ“จ ${this.id} | ${this.priority.toUpperCase()} | ${this.message} | ${this.timestamp.toLocaleTimeString()}`;
  }

  // ๐ŸŽฏ Get priority emoji
  getPriorityEmoji(): string {
    const emojis = { low: '๐ŸŸข', medium: '๐ŸŸก', high: '๐Ÿ”ด' };
    return emojis[this.priority];
  }
}

// ๐Ÿ“ง Email notification with enhanced features
class EmailNotification extends Notification {
  recipient: string;
  subject: string;
  attachments: string[];

  constructor(recipient: string, subject: string, message: string, priority: 'low' | 'medium' | 'high' = 'medium') {
    // ๐Ÿ“ž Create base notification
    super(message, priority);
    
    // โœจ Add email-specific properties
    this.recipient = recipient;
    this.subject = subject;
    this.attachments = [];
    console.log(`๐Ÿ“ง Email notification prepared for ${recipient}`);
  }

  // ๐Ÿ“Ž Add attachment
  addAttachment(filePath: string): void {
    this.attachments.push(filePath);
    console.log(`๐Ÿ“Ž Attached: ${filePath}`);
  }

  // ๐Ÿš€ Enhanced send with email-specific logic
  send(): boolean {
    // ๐Ÿ“ž Check if base send is successful
    if (!super.send()) {
      return false; // Already sent or failed
    }

    // โœจ Email-specific sending logic
    console.log(`๐Ÿ“ง Sending email to: ${this.recipient}`);
    console.log(`๐Ÿ“ Subject: ${this.subject}`);
    
    if (this.attachments.length > 0) {
      console.log(`๐Ÿ“Ž Attachments: ${this.attachments.join(', ')}`);
    }

    // ๐ŸŽฏ Priority-based delivery
    if (this.priority === 'high') {
      console.log('๐Ÿšจ HIGH PRIORITY: Sending via express delivery!');
    }

    console.log('โœ… Email delivered successfully!');
    return true;
  }

  // ๐Ÿ“Š Enhanced details with email info
  getDetails(): string {
    // ๐Ÿ“ž Get base details
    const baseDetails = super.getDetails();
    
    // โœจ Add email-specific details
    const emailInfo = `๐Ÿ“ง To: ${this.recipient} | Subject: "${this.subject}"`;
    const attachmentInfo = this.attachments.length > 0 
      ? ` | ๐Ÿ“Ž ${this.attachments.length} attachments` 
      : '';
    
    return `${baseDetails} | ${emailInfo}${attachmentInfo}`;
  }
}

// ๐Ÿ“ฑ SMS notification with character limits
class SMSNotification extends Notification {
  phoneNumber: string;
  maxLength: number = 160;

  constructor(phoneNumber: string, message: string, priority: 'low' | 'medium' | 'high' = 'medium') {
    // ๐Ÿ“ž Create base notification with truncated message if needed
    const truncatedMessage = message.length > 160 
      ? message.substring(0, 157) + '...' 
      : message;
    
    super(truncatedMessage, priority);
    
    // โœจ Add SMS-specific properties
    this.phoneNumber = phoneNumber;
    console.log(`๐Ÿ“ฑ SMS notification prepared for ${phoneNumber}`);
    
    if (message.length > 160) {
      console.log(`โš ๏ธ Message truncated from ${message.length} to ${this.message.length} characters`);
    }
  }

  // ๐Ÿš€ Enhanced send with SMS-specific features
  send(): boolean {
    // ๐Ÿ“ž Do the basic notification send
    if (!super.send()) {
      return false;
    }

    // โœจ SMS-specific logic
    console.log(`๐Ÿ“ฑ Sending SMS to: ${this.phoneNumber}`);
    console.log(`๐Ÿ“ Message (${this.message.length}/${this.maxLength} chars): "${this.message}"`);
    
    // ๐ŸŽฏ Priority affects delivery speed
    const deliveryTime = this.priority === 'high' ? 'immediate' : 'within 1 minute';
    console.log(`โฑ๏ธ Delivery time: ${deliveryTime}`);
    
    console.log('โœ… SMS sent successfully!');
    return true;
  }

  // ๐Ÿ“Š Enhanced details with SMS info
  getDetails(): string {
    // ๐Ÿ“ž Get base details
    const baseDetails = super.getDetails();
    
    // โœจ Add SMS-specific details
    const smsInfo = `๐Ÿ“ฑ To: ${this.phoneNumber} | Length: ${this.message.length}/${this.maxLength}`;
    
    return `${baseDetails} | ${smsInfo}`;
  }
}

// ๐Ÿ”” Push notification for mobile apps
class PushNotification extends Notification {
  deviceToken: string;
  appName: string;
  soundEnabled: boolean;
  badgeCount: number;

  constructor(deviceToken: string, appName: string, message: string, priority: 'low' | 'medium' | 'high' = 'medium') {
    // ๐Ÿ“ž Create base notification
    super(message, priority);
    
    // โœจ Add push-specific properties
    this.deviceToken = deviceToken;
    this.appName = appName;
    this.soundEnabled = priority !== 'low'; // Low priority = silent
    this.badgeCount = 1;
    console.log(`๐Ÿ”” Push notification prepared for ${appName}`);
  }

  // ๐Ÿ”Š Toggle sound
  toggleSound(): void {
    this.soundEnabled = !this.soundEnabled;
    console.log(`๐Ÿ”Š Sound ${this.soundEnabled ? 'enabled' : 'disabled'}`);
  }

  // ๐Ÿš€ Enhanced send with push-specific features
  send(): boolean {
    // ๐Ÿ“ž Do the basic send
    if (!super.send()) {
      return false;
    }

    // โœจ Push notification specific logic
    console.log(`๐Ÿ”” Sending push notification to ${this.appName}`);
    console.log(`๐Ÿ“ฑ Device: ${this.deviceToken.substring(0, 8)}...`);
    console.log(`๐Ÿ“ Message: "${this.message}"`);
    
    if (this.soundEnabled) {
      console.log(`๐Ÿ”Š Playing notification sound`);
    } else {
      console.log(`๐Ÿ”‡ Silent notification`);
    }

    console.log(`๐Ÿ”ข Badge count: ${this.badgeCount}`);
    console.log('โœ… Push notification delivered!');
    return true;
  }

  // ๐Ÿ“Š Enhanced details with push info
  getDetails(): string {
    // ๐Ÿ“ž Get base details
    const baseDetails = super.getDetails();
    
    // โœจ Add push-specific details
    const pushInfo = `๐Ÿ”” App: ${this.appName} | Sound: ${this.soundEnabled ? '๐Ÿ”Š' : '๐Ÿ”‡'} | Badge: ${this.badgeCount}`;
    
    return `${baseDetails} | ${pushInfo}`;
  }
}

// ๐Ÿ“ฌ Notification manager to handle all types
class NotificationManager {
  private notifications: Notification[] = [];

  addNotification(notification: Notification): void {
    this.notifications.push(notification);
    console.log(`โž• Added notification: ${notification.id}`);
  }

  sendAll(): void {
    console.log(`๐Ÿ“ค Sending ${this.notifications.length} notifications...`);
    this.notifications.forEach(notification => {
      notification.send();
    });
  }

  showAllDetails(): void {
    console.log('\n๐Ÿ“‹ All Notifications:');
    this.notifications.forEach((notification, index) => {
      console.log(`${index + 1}. ${notification.getDetails()}`);
    });
  }
}

// ๐ŸŽฎ Let's test our notification system!
const notificationManager = new NotificationManager();

// Create different types of notifications
const email = new EmailNotification(
  '[email protected]',
  'Welcome to TypeScript!',
  'Thanks for joining our TypeScript tutorial series!',
  'high'
);
email.addAttachment('welcome-guide.pdf');

const sms = new SMSNotification(
  '+1234567890',
  'Your TypeScript tutorial is ready! Click here to start learning: https://example.com/ts-tutorial-super-keyword',
  'medium'
);

const push = new PushNotification(
  'device_token_abc123xyz',
  'TypeScript Academy',
  'New lesson available: Super Keyword!',
  'high'
);

// Add to manager and send
notificationManager.addNotification(email);
notificationManager.addNotification(sms);
notificationManager.addNotification(push);

notificationManager.showAllDetails();
console.log('\n๐Ÿš€ Sending all notifications...\n');
notificationManager.sendAll();

๐Ÿš€ Advanced Concepts

๐Ÿง™โ€โ™‚๏ธ Advanced Topic 1: Super with Static Methods

You can also use super with static methods:

// ๐Ÿญ Base factory class
class VehicleFactory {
  static vehicleCount: number = 0;

  static createVehicle(): string {
    this.vehicleCount++;
    return `๐Ÿš— Vehicle #${this.vehicleCount} created`;
  }

  static getReport(): string {
    return `๐Ÿ“Š Total vehicles created: ${this.vehicleCount}`;
  }
}

// โœˆ๏ธ Specialized aircraft factory
class AircraftFactory extends VehicleFactory {
  static aircraftCount: number = 0;

  // ๐Ÿš€ Enhanced creation with aircraft specifics
  static createVehicle(): string {
    // ๐Ÿ“ž Call parent's method first
    const baseResult = super.createVehicle();
    
    // โœจ Add aircraft-specific logic
    this.aircraftCount++;
    return `${baseResult} โœˆ๏ธ (Aircraft #${this.aircraftCount})`;
  }

  // ๐Ÿ“ˆ Enhanced report with aircraft details
  static getReport(): string {
    // ๐Ÿ“ž Get base report
    const baseReport = super.getReport();
    
    // โœจ Add aircraft details
    return `${baseReport} | Aircraft: ${this.aircraftCount} โœˆ๏ธ`;
  }
}

console.log(AircraftFactory.createVehicle()); // Creates both vehicle and aircraft
console.log(AircraftFactory.createVehicle());
console.log(AircraftFactory.getReport()); // Shows both counts

๐Ÿ—๏ธ Advanced Topic 2: Super in Method Chaining

Using super with method chaining patterns:

// ๐Ÿ”— Chainable configuration class
class ConfigBuilder {
  protected config: Record<string, any> = {};

  setValue(key: string, value: any): this {
    this.config[key] = value;
    console.log(`โš™๏ธ Set ${key} = ${value}`);
    return this;
  }

  build(): Record<string, any> {
    console.log('๐Ÿ—๏ธ Configuration built!');
    return { ...this.config };
  }
}

// ๐Ÿ—„๏ธ Database configuration builder
class DatabaseConfigBuilder extends ConfigBuilder {
  // ๐Ÿš€ Enhanced setValue with validation
  setValue(key: string, value: any): this {
    // ๐Ÿ›ก๏ธ Add database-specific validation
    if (key === 'port' && (typeof value !== 'number' || value < 1 || value > 65535)) {
      console.log('โŒ Invalid port number');
      return this;
    }

    if (key === 'host' && typeof value !== 'string') {
      console.log('โŒ Host must be a string');
      return this;
    }

    // ๐Ÿ“ž Call parent's setValue if validation passes
    return super.setValue(key, value);
  }

  // ๐Ÿ—„๏ธ Database-specific methods
  setConnectionPool(size: number): this {
    return this.setValue('connectionPoolSize', size);
  }

  setSSL(enabled: boolean): this {
    return this.setValue('ssl', enabled);
  }

  // ๐Ÿš€ Enhanced build with database defaults
  build(): Record<string, any> {
    // Set defaults before building
    if (!this.config.port) this.setValue('port', 5432);
    if (!this.config.host) this.setValue('host', 'localhost');
    
    // ๐Ÿ“ž Call parent's build
    return super.build();
  }
}

// ๐Ÿ”— Method chaining in action!
const dbConfig = new DatabaseConfigBuilder()
  .setValue('database', 'typescript_tutorial')
  .setValue('username', 'dev_user')
  .setValue('port', 5432)
  .setConnectionPool(10)
  .setSSL(true)
  .build();

console.log('๐Ÿ“‹ Final config:', dbConfig);

โš ๏ธ Common Pitfalls and Solutions

๐Ÿ˜ฑ Pitfall 1: Forgetting to Call super() in Constructor

// โŒ Wrong way - missing super() call!
class BadChild extends Person {
  specialty: string;

  constructor(name: string, age: number, specialty: string) {
    // Missing super(name, age) - TypeScript will error!
    this.specialty = specialty; // ๐Ÿ’ฅ Error: must call super() first
  }
}

// โœ… Correct way - always call super() first!
class GoodChild extends Person {
  specialty: string;

  constructor(name: string, age: number, specialty: string) {
    super(name, age); // โœ… Call parent constructor first!
    this.specialty = specialty; // โœ… Now this works
  }
}

๐Ÿคฏ Pitfall 2: Using โ€˜thisโ€™ Before super()

class Parent {
  value: number;
  
  constructor(value: number) {
    this.value = value;
  }
}

// โŒ Wrong way - using 'this' before super()!
class BadChild extends Parent {
  multiplier: number;

  constructor(value: number, multiplier: number) {
    this.multiplier = multiplier; // ๐Ÿ’ฅ Error: must call super() before using 'this'
    super(value);
  }
}

// โœ… Correct way - super() first, then 'this'!
class GoodChild extends Parent {
  multiplier: number;

  constructor(value: number, multiplier: number) {
    super(value); // โœ… Call super() first
    this.multiplier = multiplier; // โœ… Now 'this' is available
  }
}

๐Ÿ”„ Pitfall 3: Infinite Recursion with super

class Parent {
  calculate(): number {
    return 42;
  }
}

// โŒ Dangerous - potential infinite loop!
class BadChild extends Parent {
  calculate(): number {
    // This calls the parent method correctly
    const parentResult = super.calculate();
    
    // But this would call itself infinitely!
    // return this.calculate() + parentResult; // ๐Ÿ’ฅ Stack overflow!
    
    return parentResult * 2; // โœ… This is correct
  }
}

๐Ÿ› ๏ธ Best Practices

  1. ๐Ÿ“ž Always Call super() First: In constructors, call super() before using this
  2. ๐ŸŽฏ Use super for Enhancement: Donโ€™t replace parent functionality, enhance it
  3. ๐Ÿ” Be Explicit: Use super.method() to make parent calls obvious
  4. โšก Call Once: Donโ€™t call the same super method multiple times unnecessarily
  5. ๐Ÿ“ Document Intent: Comment why youโ€™re calling super methods

๐Ÿงช Hands-On Exercise

๐ŸŽฏ Challenge: Build a Social Media Post System

Create a social media system where different post types enhance base functionality:

๐Ÿ“‹ Requirements:

  • โœ… Base Post class with content, author, timestamp, likes
  • ๐Ÿ“ธ PhotoPost class with image handling and filters
  • ๐Ÿ“น VideoPost class with duration and quality settings
  • ๐Ÿ“ TextPost class with character limits and hashtag extraction
  • ๐Ÿ”„ Each class should enhance parent methods using super

๐Ÿš€ Bonus Points:

  • Add comment system to all post types
  • Implement engagement scoring
  • Create post analytics features

๐Ÿ’ก Solution

๐Ÿ” Click to see solution
// ๐Ÿ“ฑ Base social media post
class Post {
  id: string;
  content: string;
  author: string;
  timestamp: Date;
  likes: number = 0;
  comments: string[] = [];

  constructor(content: string, author: string) {
    this.id = `post_${Date.now()}_${Math.random().toString(36).substr(2, 5)}`;
    this.content = content;
    this.author = author;
    this.timestamp = new Date();
    console.log(`๐Ÿ“ฑ Post created by ${author}`);
  }

  // ๐Ÿ‘ Like the post
  like(): void {
    this.likes++;
    console.log(`๐Ÿ‘ Post liked! Total likes: ${this.likes}`);
  }

  // ๐Ÿ’ฌ Add comment
  addComment(comment: string): void {
    this.comments.push(comment);
    console.log(`๐Ÿ’ฌ Comment added: "${comment}"`);
  }

  // ๐Ÿ“Š Get engagement score
  getEngagementScore(): number {
    return this.likes + (this.comments.length * 2);
  }

  // ๐Ÿ”„ Share the post
  share(): void {
    console.log(`๐Ÿ”„ "${this.content.substring(0, 30)}..." shared by ${this.author}`);
  }

  // ๐Ÿ“‹ Get post summary
  getSummary(): string {
    return `๐Ÿ“ฑ ${this.author} | ${this.timestamp.toLocaleDateString()} | ๐Ÿ‘ ${this.likes} | ๐Ÿ’ฌ ${this.comments.length}`;
  }
}

// ๐Ÿ“ธ Photo post with image features
class PhotoPost extends Post {
  imageUrl: string;
  filter: string;
  altText: string;

  constructor(content: string, author: string, imageUrl: string, altText: string = '') {
    // ๐Ÿ“ž Create base post
    super(content, author);
    
    // โœจ Add photo-specific properties
    this.imageUrl = imageUrl;
    this.filter = 'none';
    this.altText = altText;
    console.log(`๐Ÿ“ธ Photo attached: ${imageUrl}`);
  }

  // ๐ŸŽจ Apply filter
  applyFilter(filter: string): void {
    this.filter = filter;
    console.log(`๐ŸŽจ Applied ${filter} filter to photo`);
  }

  // ๐Ÿš€ Enhanced like with photo engagement
  like(): void {
    // ๐Ÿ“ž Do the basic like
    super.like();
    
    // โœจ Photo posts get bonus engagement
    if (this.likes % 10 === 0) {
      console.log(`๐Ÿ“ธ Photo milestone! ${this.likes} likes reached!`);
    }
  }

  // ๐Ÿš€ Enhanced share with image preview
  share(): void {
    // ๐Ÿ“ž Do basic share
    super.share();
    
    // โœจ Add photo-specific sharing
    console.log(`๐Ÿ–ผ๏ธ Shared with image preview: ${this.imageUrl}`);
  }

  // ๐Ÿ“Š Enhanced summary with photo info
  getSummary(): string {
    // ๐Ÿ“ž Get base summary
    const baseSummary = super.getSummary();
    
    // โœจ Add photo details
    return `${baseSummary} | ๐Ÿ“ธ Photo (${this.filter} filter)`;
  }
}

// ๐Ÿ“น Video post with media features
class VideoPost extends Post {
  videoUrl: string;
  duration: number; // in seconds
  quality: '480p' | '720p' | '1080p' | '4K';
  views: number = 0;

  constructor(content: string, author: string, videoUrl: string, duration: number, quality: '480p' | '720p' | '1080p' | '4K' = '720p') {
    // ๐Ÿ“ž Create base post
    super(content, author);
    
    // โœจ Add video-specific properties
    this.videoUrl = videoUrl;
    this.duration = duration;
    this.quality = quality;
    console.log(`๐Ÿ“น Video attached: ${this.getFormattedDuration()} at ${quality}`);
  }

  // โฏ๏ธ Play video
  play(): void {
    this.views++;
    console.log(`โ–ถ๏ธ Playing video... Views: ${this.views}`);
  }

  // ๐Ÿ• Get formatted duration
  getFormattedDuration(): string {
    const minutes = Math.floor(this.duration / 60);
    const seconds = this.duration % 60;
    return `${minutes}:${seconds.toString().padStart(2, '0')}`;
  }

  // ๐Ÿš€ Enhanced engagement score including views
  getEngagementScore(): number {
    // ๐Ÿ“ž Get base engagement
    const baseEngagement = super.getEngagementScore();
    
    // โœจ Add view-based engagement
    const viewEngagement = Math.floor(this.views / 10);
    return baseEngagement + viewEngagement;
  }

  // ๐Ÿš€ Enhanced share with video preview
  share(): void {
    // ๐Ÿ“ž Do basic share
    super.share();
    
    // โœจ Add video-specific sharing
    console.log(`๐ŸŽฌ Shared video: ${this.getFormattedDuration()} at ${this.quality}`);
  }

  // ๐Ÿ“Š Enhanced summary with video info
  getSummary(): string {
    // ๐Ÿ“ž Get base summary
    const baseSummary = super.getSummary();
    
    // โœจ Add video details
    return `${baseSummary} | ๐Ÿ“น ${this.getFormattedDuration()} (${this.views} views)`;
  }
}

// ๐Ÿ“ Text post with text processing features
class TextPost extends Post {
  hashtags: string[] = [];
  mentions: string[] = [];
  characterLimit: number = 280;

  constructor(content: string, author: string) {
    // ๐Ÿ” Process content before creating post
    const processedContent = content.length > 280 
      ? content.substring(0, 277) + '...' 
      : content;

    // ๐Ÿ“ž Create base post with processed content
    super(processedContent, author);
    
    // โœจ Extract hashtags and mentions
    this.extractHashtags();
    this.extractMentions();
    
    if (content.length > 280) {
      console.log(`โœ‚๏ธ Text truncated from ${content.length} to ${this.content.length} characters`);
    }
  }

  // ๐Ÿ” Extract hashtags from content
  private extractHashtags(): void {
    const hashtagRegex = /#(\w+)/g;
    let match;
    
    while ((match = hashtagRegex.exec(this.content)) !== null) {
      this.hashtags.push(match[1]);
    }
    
    if (this.hashtags.length > 0) {
      console.log(`๐Ÿท๏ธ Found hashtags: ${this.hashtags.join(', ')}`);
    }
  }

  // ๐Ÿ‘ฅ Extract mentions from content
  private extractMentions(): void {
    const mentionRegex = /@(\w+)/g;
    let match;
    
    while ((match = mentionRegex.exec(this.content)) !== null) {
      this.mentions.push(match[1]);
    }
    
    if (this.mentions.length > 0) {
      console.log(`๐Ÿ‘ฅ Mentioned users: ${this.mentions.join(', ')}`);
    }
  }

  // ๐Ÿš€ Enhanced share with hashtag promotion
  share(): void {
    // ๐Ÿ“ž Do basic share
    super.share();
    
    // โœจ Promote hashtags when sharing
    if (this.hashtags.length > 0) {
      console.log(`๐Ÿท๏ธ Trending hashtags: ${this.hashtags.map(tag => `#${tag}`).join(' ')}`);
    }
  }

  // ๐Ÿ“Š Enhanced summary with text features
  getSummary(): string {
    // ๐Ÿ“ž Get base summary
    const baseSummary = super.getSummary();
    
    // โœจ Add text-specific details
    const textInfo = `๐Ÿ“ ${this.content.length}/${this.characterLimit} chars`;
    const hashtagInfo = this.hashtags.length > 0 ? ` | ๐Ÿท๏ธ ${this.hashtags.length}` : '';
    const mentionInfo = this.mentions.length > 0 ? ` | ๐Ÿ‘ฅ ${this.mentions.length}` : '';
    
    return `${baseSummary} | ${textInfo}${hashtagInfo}${mentionInfo}`;
  }
}

// ๐Ÿ“ฑ Social media feed manager
class SocialFeed {
  private posts: Post[] = [];

  addPost(post: Post): void {
    this.posts.push(post);
    console.log(`โž• Added post to feed: ${post.id}`);
  }

  showFeed(): void {
    console.log('\n๐Ÿ“ฑ Social Media Feed:');
    this.posts.forEach((post, index) => {
      console.log(`${index + 1}. ${post.getSummary()}`);
    });
  }

  getTopPosts(count: number = 3): Post[] {
    return this.posts
      .sort((a, b) => b.getEngagementScore() - a.getEngagementScore())
      .slice(0, count);
  }

  getTrendingHashtags(): string[] {
    const hashtagCount = new Map<string, number>();
    
    this.posts.forEach(post => {
      if (post instanceof TextPost) {
        post.hashtags.forEach(hashtag => {
          hashtagCount.set(hashtag, (hashtagCount.get(hashtag) || 0) + 1);
        });
      }
    });

    return Array.from(hashtagCount.entries())
      .sort(([,a], [,b]) => b - a)
      .slice(0, 5)
      .map(([hashtag]) => `#${hashtag}`);
  }
}

// ๐ŸŽฎ Let's create some social media magic!
const feed = new SocialFeed();

// Create different types of posts
const textPost = new TextPost(
  'Just learned about the super keyword in #TypeScript! Amazing how it connects parent and child classes. Thanks @typescript @developer #coding #learning',
  'CodeLearner'
);

const photoPost = new PhotoPost(
  'Beautiful sunset from my coding session! ๐ŸŒ…',
  'DevPhotographer',
  'https://example.com/sunset.jpg',
  'Golden sunset over mountains with laptop in foreground'
);

const videoPost = new VideoPost(
  'TypeScript tutorial: Super keyword explained!',
  'TechTeacher',
  'https://example.com/tutorial.mp4',
  450, // 7:30 minutes
  '1080p'
);

// Add some engagement
textPost.like();
textPost.addComment('Great explanation!');
textPost.addComment('Thanks for sharing!');

photoPost.like();
photoPost.like();
photoPost.applyFilter('vintage');

videoPost.play();
videoPost.play();
videoPost.play();
videoPost.like();

// Add to feed
feed.addPost(textPost);
feed.addPost(photoPost);
feed.addPost(videoPost);

// Show results
feed.showFeed();

console.log('\n๐Ÿ† Top Posts:');
feed.getTopPosts().forEach((post, index) => {
  console.log(`${index + 1}. ${post.getSummary()} (Score: ${post.getEngagementScore()})`);
});

console.log('\n๐Ÿ”ฅ Trending Hashtags:');
console.log(feed.getTrendingHashtags().join(' '));

// Share some posts
console.log('\n๐Ÿ”„ Sharing posts...');
textPost.share();
photoPost.share();
videoPost.share();

๐ŸŽ“ Key Takeaways

Youโ€™ve mastered the super keyword! Hereโ€™s what you can now do:

  • โœ… Call parent constructors with super() ๐Ÿ“ž
  • โœ… Access parent methods effectively ๐Ÿ”ง
  • โœ… Enhance functionality without losing parent features ๐Ÿš€
  • โœ… Build proper class hierarchies with clear communication ๐Ÿ—๏ธ
  • โœ… Avoid common super pitfalls like a pro ๐Ÿ›ก๏ธ

Remember: super is your bridge to parent classes - use it to enhance, not replace! ๐ŸŒ‰

๐Ÿค Next Steps

Congratulations! ๐ŸŽ‰ Youโ€™ve mastered the super keyword!

Hereโ€™s what to do next:

  1. ๐Ÿ’ป Practice with the social media system exercise above
  2. ๐Ÿ—๏ธ Build your own class hierarchy using super effectively
  3. ๐Ÿ“š Move on to our next tutorial: Method Overriding: Customizing Inherited Behavior
  4. ๐ŸŒŸ Experiment with static super calls and advanced patterns!

Remember: Every great class hierarchy uses super effectively. Keep building, keep learning, and super-charge your TypeScript skills! ๐Ÿš€


Happy coding! ๐ŸŽ‰๐Ÿš€โœจ