Inheritance and Polymorphism
Method Overriding
A child class can override a parent method to provide specialized behavior.
override
An overriding method has the same name as the parent method and runs for the child instance.
Method Overriding
override.ts
Replay: real traced execution (multi-file project)
class Notification {
message: string;
constructor(message: string) {
this.message = message;
}
format(): string {
return this.message;
}
}
class UrgentNotification extends Notification {
format(): string {
return `URGENT: ${this.message.toUpperCase()}`;
}
}
const rawMessage: string = "build passed";
const notice: Notification = new UrgentNotification(rawMessage);
const formatted: string = notice.format();
console.log(formatted);
class Notification {
message: string;
constructor(message: string) {
this.message = message;
}
format(): string {
return this.message;
}
}
class UrgentNotification extends Notification {
format(): string {
return `URGENT: ${this.message.toUpperCase()}`;
}
}
const rawMessage: string = "tests failed";
const notice: Notification = new UrgentNotification(rawMessage);
const formatted: string = notice.format();
console.log(formatted);
class Notification {
message: string;
constructor(message: string) {
this.message = message;
}
format(): string {
return this.message;
}
}
class UrgentNotification extends Notification {
format(): string {
return `URGENT: ${this.message.toUpperCase()}`;
}
}
const rawMessage: string = "deploy ready";
const notice: Notification = new UrgentNotification(rawMessage);
const formatted: string = notice.format();
console.log(formatted);
rawMessage ← build passed, this.message ← build passed, notice ← [object Object]
4 constructor(message: string) {5 this.message = messagebuild passed;6 }78 format(): string {9 return this.message;10 }11}1213class UrgentNotification extends Notification {14 format(): string {15 return `URGENT: ${this.message.toUpperCase()}`;16 }17}1819const rawMessage→ build passed: string = "build passed"; //@rawMessage="tests failed", "deploy ready"20const notice→ [object Object]: Notification = new UrgentNotification(rawMessagebuild passed);21const formatted: string = notice[object Object].format();values this stepbuild passedthis.messageformat(): string
13class UrgentNotification extends Notification {14 format(): string {15 return `URGENT: ${this.messagebuild passed.toUpperCase()}`;16 }formatted ← URGENT: BUILD PASSED
19const rawMessage: string = "build passed"; //@rawMessage="tests failed", "deploy ready"20const notice: Notification = new UrgentNotification(rawMessage);21const formatted→ URGENT: BUILD PASSED: string = notice[object Object].format();2223console.log(formattedURGENT: BUILD PASSED);outputURGENT: BUILD PASSED
rawMessage ← tests failed, this.message ← tests failed, notice ← [object Object]
4 constructor(message: string) {5 this.message = messagetests failed;6 }78 format(): string {9 return this.message;10 }11}1213class UrgentNotification extends Notification {14 format(): string {15 return `URGENT: ${this.message.toUpperCase()}`;16 }17}1819const rawMessage→ tests failed: string = "tests failed";20const notice→ [object Object]: Notification = new UrgentNotification(rawMessagetests failed);21const formatted: string = notice[object Object].format();values this steptests failedthis.messageformat(): string
13class UrgentNotification extends Notification {14 format(): string {15 return `URGENT: ${this.messagetests failed.toUpperCase()}`;16 }formatted ← URGENT: TESTS FAILED
19const rawMessage: string = "tests failed";20const notice: Notification = new UrgentNotification(rawMessage);21const formatted→ URGENT: TESTS FAILED: string = notice[object Object].format();2223console.log(formattedURGENT: TESTS FAILED);outputURGENT: TESTS FAILED
rawMessage ← deploy ready, this.message ← deploy ready, notice ← [object Object]
4 constructor(message: string) {5 this.message = messagedeploy ready;6 }78 format(): string {9 return this.message;10 }11}1213class UrgentNotification extends Notification {14 format(): string {15 return `URGENT: ${this.message.toUpperCase()}`;16 }17}1819const rawMessage→ deploy ready: string = "deploy ready";20const notice→ [object Object]: Notification = new UrgentNotification(rawMessagedeploy ready);21const formatted: string = notice[object Object].format();values this stepdeploy readythis.messageformat(): string
13class UrgentNotification extends Notification {14 format(): string {15 return `URGENT: ${this.messagedeploy ready.toUpperCase()}`;16 }formatted ← URGENT: DEPLOY READY
19const rawMessage: string = "deploy ready";20const notice: Notification = new UrgentNotification(rawMessage);21const formatted→ URGENT: DEPLOY READY: string = notice[object Object].format();2223console.log(formattedURGENT: DEPLOY READY);outputURGENT: DEPLOY READY
Follow the Override
rawMessagestarts asbuild passed.- The variable type is
Notification, but the object isnew UrgentNotification(rawMessage). - Calling
notice.format()runs the child override. - The override uppercases the message.
- The output is
URGENT: BUILD PASSED. | message | method used | output | | --- | --- | --- | | build passed | childformat()| URGENT: BUILD PASSED | | tests failed | childformat()| URGENT: TESTS FAILED | | deploy ready | childformat()| URGENT: DEPLOY READY |
Exercise: override.ts
Reproduce URGENT: BUILD PASSED, then use the pinned rawMessage variants tests failed and deploy ready to predict URGENT: TESTS FAILED and URGENT: DEPLOY READY.