| Feature | C\# | TypeScript | JavaScript |
|---|---|---|---|
| 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) |
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 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 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();Here's how a simple vehicle hierarchy looks in each language.
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");
}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");
}
}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");
}
}