web-dev-qa-db-fra.com

Manière appropriée d'appeler des fonctions de superclasse à partir d'une sous-classe

J'ai une "SuperClass" avec "info" comme variable d'instance. "SuperClass" a la fonction "printInfo ()". "printInfo ()" doit accéder à la variable d'instance "info". Je veux créer une "SubClass" qui a également la méthode "printInfo ()". Je veux appeler printInfo () de "SuperClass" depuis "printInfo ()" de "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();

Vous pouvez voir que je passe "ça" comme paramètre à printInfo. Sans "ce" paramètre, "info" est imprimé comme "non défini". Comme dans le cas suivant, "this.info" n'est pas défini lorsque cette fonction est appelée à partir d'un objet de "SubClass".

SuperClass.prototype.printInfo = function()
    {
        console.log("printing from superclass printInfo");
        console.log(this.info);
    };

Quelle est la bonne façon de remplacer et d'appeler des méthodes de superclasse en javascript, permettant aux fonctions d'accéder aux variables d'instance de la classe?

29
coolscitist

Vous jouez avec le prototype de SubClass avec l'objet de SuperClass, dans cette ligne

SubClass.prototype = new SuperClass();

le prototype de l'enfant devrait dépendre du prototype du parent. Donc, vous pouvez hériter comme ça

SubClass.prototype = Object.create(SuperClass.prototype);

De plus, il est tout à fait normal de changer le constructeur en fonction réelle, comme ceci

SubClass.prototype.constructor = SubClass;

Pour garder votre implémentation générique, vous pouvez utiliser Object.getPrototypeOf , pour obtenir le prototype parent dans la chaîne d'héritage, puis appeler printInfo, comme ceci

SubClass.prototype.printInfo = function() {
    Object.getPrototypeOf(SubClass.prototype).printInfo(this);
};

Depuis, info est encore défini dans SubClass, il affichera undefined. Vous pouvez également appeler le constructeur parent't, comme ceci

var SubClass = function() {
    SuperClass.call(this);
};

Remarque: Vous créez des variables globales, en omettant var mot-clé avant SuperClass et SubClass.

27
thefourtheye

Après avoir lu toutes les réponses, j'utilise le mécanisme d'héritage suivant:

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();
9
coolscitist

Vous pouvez l'écrire comme ceci:

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");
};
6
Camille Wintz

Pour tous ceux qui viennent plus d'un monde Java monde, j'ignorerais tout ce qui précède et utiliserais plutôt la syntaxe suivante introduite en 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;
  }
} 

Plus d'informations sur https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

Et soudainement, vous pouvez utiliser super comme mot-clé pour accéder à l'ancêtre, etc.

4
Tom

@coolscitist

Au lieu de

SubClass.prototype.printInfo = function()
{
    Object.getPrototypeOf(SubClass.prototype).printInfo.call(this);
};

utilisez ceci

SubClass.prototype.printInfo = function()
{
    Object.getPrototypeOf(this.constructor.prototype).printInfo.call(this);
};
3
Lo HaBuyshan
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');
0
Denis Howe