When we have a subclass B that overrides a method from its superclass A in TypeScript, why does calling the method on an instance of A result in the parent class's implementation being called?
In TypeScript, consider a class called Drug
with properties name
and efficiency
, along with a method updateEfficiency()
that decreases the efficiency by 1:
class Drug {
name: string;
efficiency: number;
constructor(name: string, efficiency: number) {
this.name = name;
this.efficiency = efficiency;
}
updateEfficiency() {
this.efficiency -= 1;
}
}
We also have a class named BottleOfWine
which extends the Drug
class and overrides the updateEfficiency()
method to decrease efficiency by 2:
class BottleOfWine extends Drug {
constructor(efficiency: number) {
super("Old bottle of wine", efficiency);
}
updateEfficiency() {
this.efficiency -= 2;
}
}
Finally, there is a class called Inventory
that contains an array of drugs and a method updateAll()
to update the efficiency of all drugs:
class Inventory {
drugs: Drug[];
constructor(drugs: Drug[]) {
this.drugs = drugs;
}
updateAll() {
this.drugs.forEach((drug) => {
switch (drug.name) {
case "Old bottle of wine":
// Here I expect to call the child method that decreases the efficiency by 2,
// but the parent class is called instead
(drug as BottleOfWine).updateEfficiency();
break;
case "Insulin vial":
// Nothing to do
break;
}
});
}
}
However, when utilizing the updateAll()
method, casting the drug object into a more specific (child) entity and invoking the method from the child class doesn't behave as expected. This can be seen in the following example:
const inventory = new Inventory([new Drug("Old bottle of wine", 10)])
inventory.updateAll();
console.log(inventory.drugs[0].efficiency); // Expected output: 8 (10 - 2), Actual output: 9 (10 - 1)
Any insights into this behavior?