Isaac.

Inheritance in C\#, TypeScript, and JavaScript

Table of Contents

  • Overview Table
  • C\# Inheritance
  • TypeScript Inheritance
  • JavaScript Inheritance
  • Key Differences Summary
  • Practical Example: Cross-Language Comparison

Overview Table

FeatureC\#TypeScriptJavaScript
Class-based Inheritance✅ Full support✅ Compile-time support✅ ES6+ (syntactic sugar)
Prototype-based Inheritance❌ Not available✅ Can access underlying JS✅ Native
Multiple Inheritance❌ (Interfaces only)❌ (Interfaces only)
Access Modifiers✅ Public, Private, Protected✅ Public, Private, Protected❌ (Conventions only)
Abstract Classes❌ (Can simulate)
Interfaces❌ (Can simulate)

C\# Inheritance

In C\#, inheritance is powerful, strongly typed, and supports features like abstract classes, interfaces, and sealed methods.

// Base class
public class Animal
{
    public string Name { get; set; }
    protected int Age { get; set; }

    public Animal(string name, int age)
    {
        Name = name;
        Age = age;
    }

    public virtual void MakeSound()
    {
        Console.WriteLine("Some generic animal sound");
    }

    public sealed void Eat()
    {
        Console.WriteLine("Eating...");
    }
}

// Derived class
public class Dog : Animal
{
    public string Breed { get; set; }

    public Dog(string name, int age, string breed) : base(name, age)
    {
        Breed = breed;
    }

    public override void MakeSound()
    {
        Console.WriteLine("Woof! Woof!");
    }

    public void Fetch()
    {
        Console.WriteLine($"{Name} is fetching!");
    }
}

// Usage
var dog = new Dog("Buddy", 3, "Golden Retriever");
dog.MakeSound(); // "Woof! Woof!"
dog.Eat();       // "Eating..."

TypeScript Inheritance

TypeScript builds on JavaScript's prototype-based model with compile-time type safety and access modifiers.

// Base class
class Animal {
    public name: string;
    protected age: number;
    private id: number;

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

    public makeSound(): void {
        console.log("Some generic animal sound");
    }

    protected sleep(): void {
        console.log(`${this.name} is sleeping`);
    }
}

// Derived class
class Dog extends Animal {
    public breed: string;

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

    public makeSound(): void {
        console.log("Woof! Woof!");
    }

    public fetch(): void {
        console.log(`${this.name} is fetching!`);
        this.sleep();
    }
}

// Usage
const dog = new Dog("Buddy", 3, "Golden Retriever");
dog.makeSound(); 
dog.fetch();

JavaScript Inheritance

JavaScript natively uses prototype-based inheritance, but ES6 introduced the class syntax as syntactic sugar.

// Base class
class Animal {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    makeSound() {
        console.log("Some generic animal sound");
    }

    eat() {
        console.log("Eating...");
    }
}

// Derived class
class Dog extends Animal {
    constructor(name, age, breed) {
        super(name, age);
        this.breed = breed;
    }

    makeSound() {
        console.log("Woof! Woof!");
    }

    fetch() {
        console.log(`${this.name} is fetching!`);
    }
}

// Usage
const dog = new Dog("Buddy", 3, "Golden Retriever");
dog.makeSound(); 
dog.eat();

Key Differences Summary

Practical Example: Cross-Language Comparison

Here's how a simple vehicle hierarchy looks in each language.

C\#

public class Vehicle {
    public string Make { get; set; }
    public string Model { get; set; }

    public virtual void Start() =>
        Console.WriteLine("Vehicle starting");
}

public class Car : Vehicle {
    public int Doors { get; set; }

    public override void Start() =>
        Console.WriteLine("Car starting with key");
}

TypeScript

class Vehicle {
    constructor(public make: string, public model: string) {}

    public start(): void {
        console.log("Vehicle starting");
    }
}

class Car extends Vehicle {
    constructor(make: string, model: string, public doors: number) {
        super(make, model);
    }

    public start(): void {
        console.log("Car starting with key");
    }
}

JavaScript

class Vehicle {
    constructor(make, model) {
        this.make = make;
        this.model = model;
    }

    start() {
        console.log("Vehicle starting");
    }
}

class Car extends Vehicle {
    constructor(make, model, doors) {
        super(make, model);
        this.doors = doors;
    }

    start() {
        console.log("Car starting with key");
    }
}