如何从一个父类的方法中调用另一个父类的方法?

4

我有以下代码。如何使得当我调用rabbit.halfRun();时,它运行Animal.run()中的代码而不是Rabbit.run()中的代码?

class Animal {

  constructor(name) {
    this.speed = 0;
    this.name = name;
  }

  run(speed) {
    this.speed += speed;
    console.log(`${this.name} runs with speed ${this.speed}.`);
  }

  
  halfRun(){
    var newSpeed = this.speed / 2;
    // expect to be run() from Animal class, not Rabbit class
    this.run(newSpeed)
  }

}

class Rabbit extends Animal {

  
  run(speed) {
    var speed = speed * 2;
    super.run(speed);
  }


}

let rabbit = new Rabbit("White Rabbit");

rabbit.run(5); // expect and get 10
rabbit.halfRun(); // expect 5 but I get 20 because it is running the run() from Rabbit


只需拥有一个类似于 runImpl 的“私有”方法。 - Daniel A. White
实际上,由于super.run(speed);的存在,父类和子类的run方法都会被执行。您可以通过在Rabbit的run方法中添加console.log语句来确认这一点。 - leo.fcx
不涉及问题本身,但我认为对于 rabbit.halfRun() ,你应该期望得到 15,而不是 5。以下是序列(假设您获得了所需的行为):将 this.speed 设为 10,然后将 newSpeed 设为 5,最后将 this.speed 设为 10 + 5,得到 15 - Gerardo Furtado
那么,难道不可能从Animal中调用旧的run方法而不是Rabbit中被覆盖的方法吗?我开始觉得这是不可能的。是的,我知道两者都会执行,因为调用了Rabbit.run()并且它调用了Animal.run() - Seldon Stone
5个回答

0
你得到20的原因是因为在你的halfRun函数中:
function halfRun(){
  var newSpeed = this.speed / 2;
  this.run(newSpeed);
}

你正在调用 this.run(newSpeed),它是指兔子类的run方法而不是动物类的,因为你正在调用 rabbit.halfRun()。因此,它将调用兔子类对run()的实现,因为它已被覆盖。

此外,我认为你设置halfRun()函数的方式有误,因为尽管你将速度减半,但仍将其添加到当前速度值上。

要解决问题,你可以在halfRun函数中简单地设置速度:

function halfRun(){
  this.speed=this.speed / 2;
}

0

因为halfrun调用了两个方法。兔子类的“run”方法将其乘以2,然后兔子类的“run”方法运行动物类的超级“run”方法。因此,两个“run”方法都在起作用。


0

问题类似于:

当调用rabbit.run()时,速度变量保持值为10并打印它

速度=10

当调用rabbit.halfRun()时,它将把该值除以2,这意味着10/2是5,这应该是预期的输出

在方法结束之前,您调用了this.run(newSpeed)// this.run(5)

因此它将调用兔子类中的run方法

所以速度=速度*2 // 5 * 2

这是10

最后,您正在调用super.run(speed) // super.run(10)

由于先前已执行rabbit.run(),因此速度保持值为10

所以this.speed =+ speed // 10 =+ 10,得到20


0

就像函数重写一样,实际要调用的方法是根据它所指向的实例在运行时决定的。

因为rabbit变量指向了一个class Rabbit对象,而class Rabbit上有覆盖方法run,所以即使你从父类调用halfRun,它实际上也在调用class Rabbitrun方法。这是因为实际要调用的函数是根据rabbit变量所指向的对象在运行时决定的。

所以我认为这是预期的结果,并且很好。

但是是的,在Javascript中可能没有像self这样的关键字可以在继承时调用当前类的方法。


我接受这个答案。虽然其他所有答案都很好地解释了正在发生的事情,但它们没有回答问题:“是否可以运行 Animal.run() 而不是 Rabbit.run()。” 尽管这个答案没有告诉我如何做到这一点,但它让我知道这是不可能的。 - Seldon Stone

0
我已经添加了日志来描述代码,希望您能理解为什么结果是20。这就是您的速度变化过程:
0 -> 5*2 -> 0+10 -> 10/2 -> 5*2 -> 10+10 -> 20

class Animal {

  constructor(name) {
    this.speed = 0;
    this.name = name;
  }

  run(speed) {
    console.log(`Received ${speed} from Rabbit class`);
    console.log(`Adding ${speed} to ${this.speed}`);
    this.speed += speed;
    console.log(`Current speed at run(Animal class): ${this.speed}.`);
  }

  
  halfRun(){
    console.log(`Deviding the current speed ${this.speed} by 2`);
    var newSpeed = this.speed / 2;
    console.log(`New speed passed to Rabbit class ${newSpeed}`);
    this.run(newSpeed)
  }

}

class Rabbit extends Animal {

  
  run(speed) {
    console.log(`Current speed: ${this.speed}`);
    console.log(`Multiplying ${speed} by 2`);
    var speed = speed * 2;
    console.log(`Passing ${speed} to Animal class`);
    super.run(speed);
  }


}

let rabbit = new Rabbit("White Rabbit");

rabbit.run(5); // expect 10
rabbit.halfRun(); // expect 20


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接