Inheritance in Object-Oriented Programming

Inheritance lets a class extend another class, gaining all of its properties and methods while adding or overriding its own.

In our game engine the full hierarchy is:

Code Runner Challenge

Practice inheritance. Add a speak() override in Hero, then create a Villain class extending Enemy with a doubled attack().

View IPYNB Source
GameObject
  └── Character
        ├── Player
        └── Npc
              └── Enemy
                    └── Shark
Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

This is a 3-level inheritance chain. Each level adds behaviour on top of the one above it.

Key vocabulary:

  • extends — declares that a class inherits from a parent
  • super() — calls the parent constructor; must come before this in the child constructor
  • Method overriding — redefining a parent method in a child to change its behaviour

Real Example from the Game Engine

Below is a simplified view of how Shark is built in Shark.js:

// Shark.js (assets/js/GameEnginev1.1/Shark.js)
import Enemy from './essentials/Enemy.js';
import Player from './essentials/Player.js';

class Shark extends Enemy {          // Level 4 in hierarchy
    constructor(data = null, gameEnv = null) {
        super(data, gameEnv);        // Chains to Enemy → Npc → Character → GameObject
    }

    // Override parent's handleCollisionEvent method
    handleCollisionEvent() {
        var player = this.gameEnv.gameObjects.find(obj => obj instanceof Player);
        console.log("Shark collided with player!");
        this.velocity.x = 0;
        this.velocity.y = 0;
        this.explode(player.position.x, player.position.y);
        player.destroy();
    }
}

And the Coin class (assets/js/GameEnginev1.1/Coin.js) also uses super() with constructor chaining:

class Coin extends Npc {
    constructor(data = null, gameEnv = null) {
        const coinData = { id: data?.id || 'coin', ...data };
        super(coinData, gameEnv);   // super() must come first
        this.value = Number(data?.value ?? 1);   // then we set our own properties
        this.collected = false;
        console.log('Coin created:', this.spriteData.id, 'at position', this.position);
    }
}

Try It — Build Your Own Hierarchy

Below is a 3-level class hierarchy for game characters. Run it and then:

  1. Add a speak() method override in Hero that prints "I will protect the realm!"
  2. Create a Villain class that extends Enemy and overrides attack() to deal double damage
%%js
//CODE_RUNNER: Practice inheritance. Add a speak() override in Hero, then create a Villain class extending Enemy with a doubled attack().

// Level 1 — Base class
class GameCharacter {
    constructor(name, health) {
        this.name = name;
        this.health = health;
    }
    speak() {
        console.log(`${this.name} says: "Hello!"`)
    }
    status() {
        console.log(`${this.name} — HP: ${this.health}`);
    }
}

// Level 2 — Extends GameCharacter
class Enemy extends GameCharacter {
    constructor(name, health, damage) {
        super(name, health);         // chain to parent constructor
        this.damage = damage;
    }
    attack(target) {
        target.health -= this.damage;
        console.log(`${this.name} attacks ${target.name} for ${this.damage} damage!`);
    }
}

// Level 3 — Extends Enemy
class Hero extends GameCharacter {
    constructor(name, health, shield) {
        super(name, health);
        this.shield = shield;
    }
    defend() {
        console.log(`${this.name} raises their shield (${this.shield} block)!`);
    }
    // TODO: override speak() here
}

// --- Test it ---
const hero  = new Hero('Seonyoo', 100, 30);
const shark = new Enemy('Shark', 60, 25);

hero.speak();
hero.status();
shark.attack(hero);
hero.status();
hero.defend();

// TODO: create a Villain class below and test it

Key Takeaways

Concept Keyword What it does
Inheritance extends Child class gets all parent properties/methods
Constructor chaining super(args) Runs parent constructor before child sets this
Method overriding Redefine method Child replaces or extends parent behaviour
Polymorphism Overriding Same method name, different behaviour per class