Isaac.

Polymorphism in C\#, TypeScript, and JavaScript

Polymorphism is a fundamental concept in object-oriented programming (OOP) that allows objects of different types to be treated as objects of a common super type. Below, we explore how polymorphism is implemented in C\#, TypeScript, and JavaScript.

C\# Polymorphism

1. Inheritance-Based Polymorphism

// Base class
public abstract class Shape {
  public abstract double Area();
}

// Derived classes
public class Circle : Shape {
  public double Radius { get; set; }
  public override double Area() => Math.PI * Radius * Radius;
}

public class Rectangle : Shape {
  public double Width { get; set; }
  public double Height { get; set; }
  public override double Area() => Width * Height;
}

List<Shape> shapes = new List<Shape> {
  new Circle { Radius = 5 },
  new Rectangle { Width = 4, Height = 6 }
};

foreach (Shape shape in shapes) {
  Console.WriteLine($@"Area: {shape.Area()}");
}

2. Interface Polymorphism

public interface IDrawable {
  void Draw();
}

public class Circle : IDrawable {
  public void Draw() => Console.WriteLine("Drawing circle");
}

public class Square : IDrawable {
  public void Draw() => Console.WriteLine("Drawing square");
}

List<IDrawable> drawables = new List<IDrawable> { new Circle(), new Square() };
foreach (var drawable in drawables) {
  drawable.Draw();
}

TypeScript Polymorphism

1. Class-Based Polymorphism

abstract class Animal {
  constructor(public name: string) {}

  abstract makeSound(): string;

  move(distance: number = 0): void {
    console.log(`${this.name} moved ${distance}m`);
  }
}

class Dog extends Animal {
  makeSound(): string {
    return "Woof! Woof!";
  }
}

class Cat extends Animal {
  makeSound(): string {
    return "Meow!";
  }
}

const animals: Animal[] = [new Dog("Buddy"), new Cat("Whiskers")];
animals.forEach(animal => {
  console.log(`${animal.name} says: ${animal.makeSound()} `);
  animal.move(10);
});

2. Interface Polymorphism

interface Vehicle {
  start(): void;
  stop(): void;
}

class Car implements Vehicle {
  start(): void { console.log("Car starting..."); }
  stop(): void { console.log("Car stopping..."); }
}

class Bike implements Vehicle {
  start(): void { console.log("Bike pedaling..."); }
  stop(): void { console.log("Bike braking..."); }
}

function operateVehicle(vehicle: Vehicle): void {
  vehicle.start();
  vehicle.stop();
}

operateVehicle(new Car());
operateVehicle(new Bike());

JavaScript Polymorphism

1. Prototype-Based Polymorphism

function Animal(name) {
  this.name = name;
}

Animal.prototype.makeSound = function() {
  throw new Error("Abstract method: makeSound must be implemented");
};
Animal.prototype.move = function(distance = 0) {
  console.log(`${this.name} moved ${distance}m`);
};

function Dog(name) { Animal.call(this, name); }
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.makeSound = function() {
  return "Woof! Woof!";
};

function Cat(name) { Animal.call(this, name); }
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;
Cat.prototype.makeSound = function() {
  return "Meow!";
};

const animals = [new Dog("Buddy"), new Cat("Whiskers")]; animals.forEach(animal => {
  console.log(`${animal.name} says: ${animal.makeSound()} `);
  animal.move(10);
});

Key Differences Summary

FeatureC\#TypeScriptJavaScript
Compile-time checkingStrongStrongWeak
Interface enforcementStrictStructuralN/A
InheritanceClass-basedClass-basedPrototype-based
Abstract classesSupportedSupportedNot supported

Common Polymorphism Patterns

1. Strategy Pattern

interface PaymentStrategy {
  pay(amount: number): void;
}

class CreditCardPayment implements PaymentStrategy {
  pay(amount: number): void {
    console.log(`Paid $${amount} using Credit Card`);
  }
}

class PayPalPayment implements PaymentStrategy {
  pay(amount: number): void {
    console.log(`Paid $${amount} using PayPal`);
  }
}

class PaymentProcessor {
  constructor(private strategy: PaymentStrategy) {}
  processPayment(amount: number): void {
    this.strategy.pay(amount);
  }
  setStrategy(strategy: PaymentStrategy): void {
    this.strategy = strategy;
  }
}

const processor = new PaymentProcessor(new CreditCardPayment());
processor.processPayment(100);
processor.setStrategy(new PayPalPayment());
processor.processPayment(200);

Polymorphism enables developers to write flexible, maintainable code by allowing different implementations to be used interchangeably through common interfaces or base types.