Method Overriding
Learn about method overriding and polymorphism
What is Method Overriding?
Method Overriding means creating a new version of a parent class’s method in a child class. Instead of using the parent’s method, the child uses its own customized version.
Why Use Method Overriding?
- Customization - Each child class can have its own version of a method
- Polymorphism - Same method name, different behavior depending on the object type
- Flexibility - Child classes don’t need the parent’s exact behavior
- Code Reuse with Differences - Keep shared code in parent, customize in children
- Cleaner Code - Avoid tons of if-statements checking object types
Parent Class: Enemy
class Enemy {
constructor(data = null, gameEnv = null) {
this.gameEnv = gameEnv;
this.playerDestroyed = false;
this.position = { x: 0, y: 0 };
this.velocity = { x: 0, y: 0 };
// ... other properties
}
// Parent method - basic behavior
handleCollisionEvent() {
console.log("Generic collision event");
}
// Parent method - basic boundary check
stayWithinCanvas() {
// Stop at edges
if (this.position.x < 0) this.position.x = 0;
if (this.position.x > this.gameEnv.innerWidth) this.position.x = this.gameEnv.innerWidth;
}
}
Child Class 1: Guard (Overrides Methods)
import Enemy from '@assets/js/GameEnginev1/essentials/Enemy.js';
import Player from '@assets/js/GameEnginev1/essentials/Player.js';
class Guard extends Enemy {
constructor(data = null, gameEnv = null) {
super(data, gameEnv);
this.velocity.y = -3;
}
// Override: Guard has its own collision handling
handleCollisionEvent() {
var player = this.gameEnv.gameObjects.find(obj => obj instanceof Player);
console.log("Collision has occurred, player has been destroyed.");
player.destroy();
this.playerDestroyed = true;
}
// Override: Guard bounces off edges instead of stopping
stayWithinCanvas() {
// Bottom of canvas
if (this.position.y + this.height > this.gameEnv.innerHeight) {
this.position.y = this.gameEnv.innerHeight - this.height;
this.velocity.y *= -1; // Bounce!
}
// Top of canvas
if (this.position.y < 0) {
this.position.y = 1;
this.velocity.y *= -1; // Bounce!
}
// Left and right
if (this.position.x + this.width > this.gameEnv.innerWidth) {
this.position.x = this.gameEnv.innerWidth - this.width;
this.velocity.x = 0;
}
if (this.position.x < 0) {
this.position.x = 0;
this.velocity.x = 0;
}
}
}
Child Class 2: ExampleEnemy (Also Overrides)
import Enemy from '@assets/js/GameEnginev1/essentials/Enemy.js';
import Player from '@assets/js/GameEnginev1/essentials/Player.js';
class ExampleEnemy extends Enemy {
constructor(data = null, gameEnv = null) {
super(data, gameEnv);
}
// Override: ExampleEnemy has its own collision handling (same as Guard)
handleCollisionEvent() {
var player = this.gameEnv.gameObjects.find(obj => obj instanceof Player);
console.log("Collision has occurred, player has been destroyed.");
player.destroy();
this.playerDestroyed = true;
}
// ExampleEnemy does NOT override stayWithinCanvas()
// So it uses the parent Enemy's version
}
Try It Yourself
%%js // CODE_RUNNER: method-overriding class Character { attack() { return “Generic attack”; } } class Warrior extends Character { attack() { return “Sword attack!”; } } const warrior = new Warrior(); console.log(warrior.attack());