✅ Method Overriding
Method overriding happens when a child class (subclass) provides its own version of a method that already exists in the parent class (superclass).
Key points
Method names must be same in both classes
The child method replaces the parent method only for that class
Useful when child needs specialized behavior
Parent method is not deleted, just shadowed
Simple Example
class Animal {
speak() {
console.log("Animal makes a sound");
}
}
class Dog extends Animal {
speak() {
console.log("Dog barks");
}
}
const d = new Dog();
d.speak(); // Dog barks✔ Dog overrides speak() from Animal
✔ Calling speak() uses the child version
<div class="infographic-jsoverride">
<style>
.infographic-jsoverride {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--line: #ddd6c9;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--ok: #1a7f4e;
--ok-soft: #e3f5ec;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', -apple-system, sans-serif;
--mono-font: 'IBM Plex Mono', 'Courier New', monospace;
margin: 0 auto;
box-sizing: border-box;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-jsoverride[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--line: #2c313d;
--accent: #5b8def;
--accent-soft:#202942;
--ok: #5cd6a0;
--ok-soft: #16342a;
}
.infographic-jsoverride * { box-sizing: border-box; }
.infographic-jsoverride .ig-inner { padding: 1.75rem clamp(1.25rem, 5vw, 3rem) 2rem; }
.infographic-jsoverride .ig-title {
font-family: var(--display-font); font-size: clamp(1.4rem, 4.5vw, 1.9rem);
font-weight: 600; text-align: center; margin: 0 0 1.5rem;
}
.infographic-jsoverride .card {
border: 2px solid var(--accent); background: var(--accent-soft); border-radius: 10px; padding: 0.9rem 1rem;
transition: opacity 0.35s ease;
}
.infographic-jsoverride .card-title { font-family: var(--mono-font); font-size: 0.85rem; font-weight: 700; text-align: center; color: var(--accent); margin-bottom: 0.5rem; }
.infographic-jsoverride .method-tag {
display: block; width: fit-content; margin: 0 auto; font-family: var(--mono-font); font-size: 0.78rem; font-weight: 700;
padding: 0.3rem 0.65rem; border-radius: 5px; border: 1px solid var(--accent); color: var(--accent); background: var(--paper);
transition: opacity 0.35s ease, text-decoration 0.2s ease;
}
.infographic-jsoverride .card.is-shadowed { opacity: 0.5; }
.infographic-jsoverride .card.is-shadowed .method-tag { text-decoration: line-through; }
.infographic-jsoverride .shadow-note {
text-align: center; font-size: 0.68rem; color: var(--ink-soft); margin-top: 0.4rem;
opacity: 0; transition: opacity 0.35s ease;
}
.infographic-jsoverride .card.is-shadowed .shadow-note { opacity: 1; }
.infographic-jsoverride .link-row { display: flex; flex-direction: column; align-items: center; margin: 0.3rem 0; }
.infographic-jsoverride .link-arrow { font-size: 1.1rem; color: var(--ink-soft); }
.infographic-jsoverride .link-label { font-family: var(--mono-font); font-size: 0.7rem; color: var(--ink-soft); }
.infographic-jsoverride .child-card {
border: 2px solid var(--ok); background: var(--ok-soft); border-radius: 10px; padding: 0.9rem 1rem;
transition: box-shadow 0.3s ease, transform 0.3s ease;
}
.infographic-jsoverride .child-card .card-title { color: var(--ok); }
.infographic-jsoverride .child-card .card-title .super { color: var(--ink-soft); font-weight: 400; }
.infographic-jsoverride .child-card .method-tag { border-color: var(--ok); color: var(--ok); }
.infographic-jsoverride .child-card.is-winning { box-shadow: 0 4px 14px rgba(0,0,0,0.15); transform: translateY(-2px); }
.infographic-jsoverride .run-row { display: flex; justify-content: center; margin: 1.5rem 0 1rem; }
.infographic-jsoverride .run-btn {
font: inherit; font-size: 0.85rem; font-weight: 700; border: none; background: var(--ink);
color: var(--paper); padding: 0.6rem 1.3rem; border-radius: 999px; cursor: pointer; font-family: var(--mono-font);
}
.infographic-jsoverride .run-btn:hover { opacity: 0.88; }
.infographic-jsoverride .terminal {
background: #1e1e1e; border-radius: 8px; overflow: hidden; box-shadow: 0 8px 20px rgba(0,0,0,0.22);
}
.infographic-jsoverride .term-bar { display: flex; gap: 0.4rem; padding: 0.5rem 0.65rem; background: #2d2d2d; }
.infographic-jsoverride .term-dot { width: 0.6rem; height: 0.6rem; border-radius: 50%; }
.infographic-jsoverride .term-dot.red { background: #ff5f56; }
.infographic-jsoverride .term-dot.yellow { background: #ffbd2e; }
.infographic-jsoverride .term-dot.green { background: #27c93f; }
.infographic-jsoverride .term-body { font-family: var(--mono-font); font-size: 0.85rem; padding: 0.9rem 1rem; min-height: 2.2rem; color: #d4d4d4; }
.infographic-jsoverride .term-line { opacity: 0; transform: translateY(4px); transition: opacity 0.3s ease, transform 0.3s ease; }
.infographic-jsoverride .term-line.is-in { opacity: 1; transform: translateY(0); }
.infographic-jsoverride .term-prompt { color: #6a9955; }
.infographic-jsoverride .term-output { color: #6bcf7f; font-weight: 700; }
.infographic-jsoverride .caption {
text-align: center; font-size: 0.82rem; color: var(--ink-soft); margin-top: 1rem; min-height: 1.2em;
}
.infographic-jsoverride .caption strong { color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
.infographic-jsoverride *, .infographic-jsoverride *::before, .infographic-jsoverride *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="ig-inner">
<h2 class="ig-title">Method Overriding</h2>
<div class="card" id="parentCard">
<div class="card-title">class Animal</div>
<span class="method-tag">speak()</span>
<div class="shadow-note">shadowed — not deleted, just hidden for Dog</div>
</div>
<div class="link-row">
<span class="link-arrow">↑</span>
<span class="link-label">extends</span>
</div>
<div class="child-card" id="childCard">
<div class="card-title">class Dog <span class="super">extends Animal</span></div>
<span class="method-tag">speak()</span>
</div>
<div class="run-row">
<button class="run-btn" id="runBtn">▶ d.speak()</button>
</div>
<div class="terminal">
<div class="term-bar"><span class="term-dot red"></span><span class="term-dot yellow"></span><span class="term-dot green"></span></div>
<div class="term-body">
<div class="term-line" id="termLine"><span class="term-prompt">></span> <span class="term-output">Dog barks</span></div>
</div>
</div>
<p class="caption" id="caption">Both classes define <strong>speak()</strong> — the child's version wins.</p>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-jsoverride')
|| document.querySelector('.infographic-jsoverride');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
const runBtn = wrapper.querySelector('#runBtn');
const parentCard = wrapper.querySelector('#parentCard');
const childCard = wrapper.querySelector('#childCard');
const termLine = wrapper.querySelector('#termLine');
const caption = wrapper.querySelector('#caption');
let ran = false;
function run() {
parentCard.classList.add('is-shadowed');
childCard.classList.add('is-winning');
termLine.classList.add('is-in');
caption.innerHTML = `<strong>d.speak()</strong> calls Dog's version — Animal's still exists, just shadowed`;
ran = true;
runBtn.textContent = '⟲ Reset';
}
function reset() {
parentCard.classList.remove('is-shadowed');
childCard.classList.remove('is-winning');
termLine.classList.remove('is-in');
caption.innerHTML = `Both classes define <strong>speak()</strong> — the child's version wins.`;
ran = false;
runBtn.textContent = '▶ d.speak()';
}
runBtn.addEventListener('click', () => ran ? reset() : run());
})();
</script>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});✅ Why Do We Use Method Overriding?
To customize behavior in child classes
To add more specific functionality
To keep common logic in parent, variations in child
💡 Real-life example
Vehicle→start()generic start mechanism
ElectricCaroverridesstart()starts silently using battery
Truckoverridesstart()engine ignition + warm-up
✅ super.method()
super allows the child class to access methods (or constructor) of the parent class.
When you want to extend the parent behavior, not completely replace it
To reuse parent logic and then add extra steps
Example Using super.speak()
class Animal {
speak() {
console.log("Animal makes a sound");
}
}
class Dog extends Animal {
speak() {
super.speak(); // calls parent version
console.log("Dog barks");
}
}
const d = new Dog();
d.speak();Animal makes a sound
Dog barks✔ First runs parent method
✔ Then continues child behavior
<div class="infographic-jssuper">
<style>
.infographic-jssuper {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--line: #ddd6c9;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--ok: #1a7f4e;
--ok-soft: #e3f5ec;
--display-font: 'Fraunces', Georgia, serif;
--body-font: 'Inter', -apple-system, sans-serif;
--mono-font: 'IBM Plex Mono', 'Courier New', monospace;
margin: 0 auto;
box-sizing: border-box;
font-family: var(--body-font);
color: var(--ink);
background: var(--paper);
}
.infographic-jssuper[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--line: #2c313d;
--accent: #5b8def;
--accent-soft:#202942;
--ok: #5cd6a0;
--ok-soft: #16342a;
}
.infographic-jssuper * { box-sizing: border-box; }
.infographic-jssuper .ig-inner { padding: 1.75rem clamp(1.25rem, 5vw, 3rem) 2rem; }
.infographic-jssuper .ig-title {
font-family: var(--display-font); font-size: clamp(1.4rem, 4.5vw, 1.9rem);
font-weight: 600; text-align: center; margin: 0 0 1.5rem;
}
.infographic-jssuper .card {
border: 2px solid var(--accent); background: var(--accent-soft); border-radius: 10px; padding: 0.9rem 1rem;
transition: box-shadow 0.3s ease, transform 0.3s ease;
}
.infographic-jssuper .card.is-active { box-shadow: 0 4px 14px rgba(0,0,0,0.15); transform: translateY(-2px); }
.infographic-jssuper .card-title { font-family: var(--mono-font); font-size: 0.85rem; font-weight: 700; text-align: center; color: var(--accent); margin-bottom: 0.5rem; }
.infographic-jssuper .method-tag {
display: block; width: fit-content; margin: 0 auto; font-family: var(--mono-font); font-size: 0.78rem; font-weight: 700;
padding: 0.3rem 0.65rem; border-radius: 5px; border: 1px solid var(--accent); color: var(--accent); background: var(--paper);
}
.infographic-jssuper .link-row { display: flex; flex-direction: column; align-items: center; margin: 0.3rem 0; }
.infographic-jssuper .link-arrow { font-size: 1.1rem; color: var(--ink-soft); }
.infographic-jssuper .link-label { font-family: var(--mono-font); font-size: 0.7rem; color: var(--ink-soft); }
.infographic-jssuper .child-card {
border: 2px solid var(--ok); background: var(--ok-soft); border-radius: 10px; padding: 0.9rem 1rem;
transition: box-shadow 0.3s ease, transform 0.3s ease;
}
.infographic-jssuper .child-card.is-active { box-shadow: 0 4px 14px rgba(0,0,0,0.15); transform: translateY(-2px); }
.infographic-jssuper .child-card .card-title { color: var(--ok); }
.infographic-jssuper .child-card .card-title .super-word { color: var(--ink-soft); font-weight: 400; }
.infographic-jssuper .child-body { display: flex; flex-direction: column; align-items: center; gap: 0.3rem; }
.infographic-jssuper .super-call {
font-family: var(--mono-font); font-size: 0.72rem; font-weight: 700; padding: 0.25rem 0.55rem; border-radius: 5px;
border: 1px dashed var(--accent); color: var(--accent); background: var(--paper);
}
.infographic-jssuper .child-card .method-tag { border-color: var(--ok); color: var(--ok); }
.infographic-jssuper .run-row { display: flex; justify-content: center; margin: 1.5rem 0 1rem; }
.infographic-jssuper .run-btn {
font: inherit; font-size: 0.85rem; font-weight: 700; border: none; background: var(--ink);
color: var(--paper); padding: 0.6rem 1.3rem; border-radius: 999px; cursor: pointer; font-family: var(--mono-font);
}
.infographic-jssuper .run-btn:hover:not(:disabled) { opacity: 0.88; }
.infographic-jssuper .run-btn:disabled { opacity: 0.55; cursor: default; }
.infographic-jssuper .terminal {
background: #1e1e1e; border-radius: 8px; overflow: hidden; box-shadow: 0 8px 20px rgba(0,0,0,0.22);
}
.infographic-jssuper .term-bar { display: flex; gap: 0.4rem; padding: 0.5rem 0.65rem; background: #2d2d2d; }
.infographic-jssuper .term-dot { width: 0.6rem; height: 0.6rem; border-radius: 50%; }
.infographic-jssuper .term-dot.red { background: #ff5f56; }
.infographic-jssuper .term-dot.yellow { background: #ffbd2e; }
.infographic-jssuper .term-dot.green { background: #27c93f; }
.infographic-jssuper .term-body { font-family: var(--mono-font); font-size: 0.85rem; padding: 0.9rem 1rem; min-height: 3.6rem; color: #d4d4d4; line-height: 1.7; }
.infographic-jssuper .term-line { opacity: 0; transform: translateY(4px); transition: opacity 0.3s ease, transform 0.3s ease; }
.infographic-jssuper .term-line.is-in { opacity: 1; transform: translateY(0); }
.infographic-jssuper .term-prompt { color: #6a9955; }
.infographic-jssuper .term-output { color: #6bcf7f; font-weight: 700; }
.infographic-jssuper .caption {
text-align: center; font-size: 0.82rem; color: var(--ink-soft); margin-top: 1rem; min-height: 1.2em;
}
.infographic-jssuper .caption strong { color: var(--ink); }
@media (prefers-reduced-motion: reduce) {
.infographic-jssuper *, .infographic-jssuper *::before, .infographic-jssuper *::after {
animation-duration: 0.001ms !important; transition-duration: 0.001ms !important;
}
}
</style>
<div class="ig-inner">
<h2 class="ig-title">super.method()</h2>
<div class="card" id="parentCard">
<div class="card-title">class Animal</div>
<span class="method-tag">speak()</span>
</div>
<div class="link-row">
<span class="link-arrow">↑</span>
<span class="link-label">extends</span>
</div>
<div class="child-card" id="childCard">
<div class="card-title">class Dog <span class="super-word">extends Animal</span></div>
<div class="child-body">
<span class="super-call">super.speak()</span>
<span class="method-tag">+ "Dog barks"</span>
</div>
</div>
<div class="run-row">
<button class="run-btn" id="runBtn">▶ d.speak()</button>
</div>
<div class="terminal">
<div class="term-bar"><span class="term-dot red"></span><span class="term-dot yellow"></span><span class="term-dot green"></span></div>
<div class="term-body">
<div class="term-line" id="line1"><span class="term-prompt">></span> <span class="term-output">Animal makes a sound</span></div>
<div class="term-line" id="line2"><span class="term-prompt">></span> <span class="term-output">Dog barks</span></div>
</div>
</div>
<p class="caption" id="caption">Dog's <strong>speak()</strong> reuses Animal's version, then adds its own line.</p>
</div>
</div>
<script>
(function () {
const wrapper = document.currentScript.closest('.infographic-jssuper')
|| document.querySelector('.infographic-jssuper');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
const runBtn = wrapper.querySelector('#runBtn');
const parentCard = wrapper.querySelector('#parentCard');
const childCard = wrapper.querySelector('#childCard');
const line1 = wrapper.querySelector('#line1');
const line2 = wrapper.querySelector('#line2');
const caption = wrapper.querySelector('#caption');
function reset() {
parentCard.classList.remove('is-active');
childCard.classList.remove('is-active');
line1.classList.remove('is-in');
line2.classList.remove('is-in');
}
function run() {
reset();
runBtn.disabled = true;
childCard.classList.add('is-active');
caption.innerHTML = `Dog's <strong>speak()</strong> runs first, and calls <strong>super.speak()</strong>…`;
setTimeout(() => {
parentCard.classList.add('is-active');
line1.classList.add('is-in');
caption.innerHTML = `<strong>super.speak()</strong> jumps up to Animal's version — it runs first`;
}, 500);
setTimeout(() => {
parentCard.classList.remove('is-active');
line2.classList.add('is-in');
caption.innerHTML = `back in Dog's <strong>speak()</strong> — the rest of its own code runs next`;
runBtn.disabled = false;
}, 1300);
}
runBtn.addEventListener('click', run);
})();
</script>.demo {
font-family: system-ui, sans-serif;
padding: 16px;
}
.demo h1 {
color: #2563eb;
margin: 0 0 8px;
}
.demo p {
color: #4b5563;
margin: 0;
}document.querySelector('.demo h1')?.addEventListener('click', () => {
alert('Hello from live preview!');
});✅ Important Notes
✔ Overriding ≠ Overloading (JS does not support method overloading natively)
✔ super.method() can only be used inside a class
✔ If child does not override, parent method is used automatically
✔ Arrow functions cannot be used as class methods for overriding (they don't go to prototype)