Reputation: 3377
I have a "SuperClass" with "info" as an instance variable. "SuperClass" has function "printInfo()". "printInfo()" needs to access instance variable "info". I want to create a "SubClass" which also has method "printInfo()". I want to call printInfo() of "SuperClass" from "printInfo()" of "SubClass".
SuperClass = function()
{
this.info = "I am superclass";
console.log("SuperClass:");
};
SuperClass.prototype.printInfo = function(that)
{
console.log("printing from superclass printInfo");
console.log(that.info);
};
SubClass = function(){};
SubClass.prototype = new SuperClass();
SubClass.prototype.printInfo = function()
{
console.log("calling superclass");
this.constructor.prototype.printInfo(this);
console.log("called superclass");
};
var sc = new SubClass();
sc.printInfo();
You can see that I am passing "that" as a parameter to printInfo. Without "that" parameter, "info" is printed as "undefined". Like in the following case, "this.info" is undefined when this function is called from object of "SubClass".
SuperClass.prototype.printInfo = function()
{
console.log("printing from superclass printInfo");
console.log(this.info);
};
What is the proper way to override and invoke methods of superclass in javascript, enabling functions to access instance variables of the class?
Upvotes: 38
Views: 44824
Reputation: 269
The only way I've been able to sort this out is to save the parent's function in different variable before overriding in the child class definition.
var Foo = function(){
var self = this.
this.init = function(a,b){
self.a = a;
seld.b = b;
};
}
var Goo = function(){
Foo.apply(this);
var self = this;
self.Foo = { init: self.init };//saves the super class's definition of init in a new variable
self.init = function(a,b,c){
self.Foo.init(a,b);//can call the super class function
self.c = c;
};
}
var a = new Foo();
a.init(1,2);
var b = new Goo();
b.init(1,2,3);
Upvotes: 0
Reputation: 2411
class Thing {
constructor(age) { this.age = age; }
die(how) { console.log(`Died of ${how}`); }
}
class Me extends Thing {
constructor() { super(59); console.log(`I am ${this.age}`); }
// Refer to a method from the superclass that is overridden in the subclass
die(how) { super.die('liver failure'); console.log(`while ${how}`) }
}
(new Me()).die('hang gliding');
Upvotes: 13
Reputation: 3377
After reading all the answers, I am using the following inheritance mechanism:
var SuperClass = function()
{
this.info = "I am superclass";
console.log("SuperClass:");
};
SuperClass.prototype.printInfo = function()
{
console.log("printing from superclass printInfo");
console.log("printinfo");
console.log(this.info);
};
var SubClass = function(){
SuperClass.call(this);
};
SubClass.prototype = Object.create(SuperClass.prototype);
SubClass.prototype.constructor = SubClass;
SubClass.prototype.printInfo = function()
{
console.log("calling superclass");
Object.getPrototypeOf(SubClass.prototype).printInfo.call(this);
console.log("called superclass");
};
var sc = new SubClass();
sc.printInfo();
Upvotes: 10
Reputation: 1389
For anybody who comes more from a Java world I would ignore all of the above and use the following syntax instead that was introduced in 2015
class Polygon {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
class Square extends Polygon {
constructor(sideLength) {
super(sideLength, sideLength);
}
get area() {
return this.height * this.width;
}
set sideLength(newLength) {
this.height = newLength;
this.width = newLength;
}
}
More info on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
And suddently u can use super as keyword to access ancester etc.... For me finding this was a big relief
Upvotes: 5
Reputation: 369
@coolscitist
Instead of
SubClass.prototype.printInfo = function()
{
Object.getPrototypeOf(SubClass.prototype).printInfo.call(this);
};
use this
SubClass.prototype.printInfo = function()
{
Object.getPrototypeOf(this.constructor.prototype).printInfo.call(this);
};
Upvotes: 2
Reputation: 239453
You are messing with the SubClass
's prototype with the SuperClass
's object, in this line
SubClass.prototype = new SuperClass();
the child's prototype should depend on the Parent's prototype. So, you can inherit like this
SubClass.prototype = Object.create(SuperClass.prototype);
Also, it is quite normal to change the constructor to the actual function, like this
SubClass.prototype.constructor = SubClass;
To keep your implementation generic, you can use Object.getPrototypeOf
, to get the parent prototype in the inheritance chain and then invoke printInfo
, like this
SubClass.prototype.printInfo = function() {
Object.getPrototypeOf(SubClass.prototype).printInfo(this);
};
Since, info
is defined in the SubClass
yet, it will print undefined
. You might also want to call the parent't constructor, like this
var SubClass = function() {
SuperClass.call(this);
};
Note: You are creating global variables, by omitting var
keyword before SuperClass
and SubClass
.
Upvotes: 30
Reputation: 951
You can write it like this :
SuperClass.prototype.printInfo = function(){
console.log("printing from superclass printInfo");
console.log(this.info);
};
SubClass.prototype.printInfo = function(){
console.log("calling superclass");
SuperClass.prototype.printInfo.call(this);
console.log("called superclass");
};
Upvotes: 7