简体   繁体   English

如何在类外调用超类方法?

[英]How to call a super class method outside a class?

I have a class BMW that extends the class Car and override a method printModel: 我有一个BMW类,它扩展了Car类并覆盖了printModel方法:

 class Car{ constructor(model){ this.model = model } printModel(){ console.log(this.model) } } class BMW extends Car{ constructor(model, color){ super(model); this.color = color } printModel(){ console.log(this.model, this.color) } } let bmw = new BMW('F6', 'blue') bmw.printModel() //will print : 'F6 blue' bmw.super.printModel()// expected: 'F6' but not working 

How to call a class super method on an instance of this BMW class? 如何在此BMW类的实例上调用类的超级方法?

You'll need a way to eventually get to super when calling something on the instantiation. 您需要一种方法来最终在实例化上调用某些东西时达到super One option is to define another method on BMW that calls super.printModel : 一种选择是在BMW上定义另一种调用super.printModel

 class Car { constructor(model) { this.model = model } printModel() { console.log(this.model) } } class BMW extends Car { constructor(model, color) { super(model); this.color = color } printModelBMW() { console.log(this.model, this.color) } printModelCar() { super.printModel(); } } let bmw = new BMW('F6', 'blue') bmw.printModelBMW() //will print : 'F6 blue' bmw.printModelCar() // expected: 'F6' 

It's not possible to reference the super instance outside of the context of the class. 在类的上下文之外无法引用超级实例。 If you really must use the method from the super instance from outside of the class, you can call the method yourself: 如果确实必须从类外部使用超级实例中的方法,则可以自己调用该方法:

Car.prototype.printModel.call(bmw);

The super keyword can only be used inside a class, not outside. super关键字只能在类内部使用,而不能在外部使用。 It's technically possible to call Car 's printModel method directly, but this should really be avoided. 从技术上讲,可以直接调用CarprintModel方法,但应避免这种情况。 The whole point of overriding a method in a superclass (like printModel ) is to give it an implementation more appropriate to the subclass. 覆盖超类(如printModel )中的方法的全部printModel是为它提供一个更适合于子类的实现。 So circumventing this is an indication of improper OO design. 因此,规避这表明OO设计不正确。

However, for educational purposes I figure it would still be useful to know how this can technically be done, since it reveals how JS classes are really still using prototypes under the hood: 但是,出于教育目的,我认为了解如何在技术上进行仍然很有用,因为它揭示了JS类实际上仍在使用原型的情况:

Car.prototype.printModel.call(bmw)

One way to improve the design to avoid this would be to add an optional argument to specify how you want to print the model: 避免这种情况的一种改进设计的方法是添加一个可选参数,以指定要如何打印模型:

class BMW extends Car{
    constructor(model, color){
        super(model)
        this.color = color
    }
    printModel(includeColor){
        if (includeColor) {
            console.log(this.model, this.color)
        }
        else super.printModel()
    }
}
class Car{
    constructor(model){
       this.model = model
    }
    printModel(){
    console.log(this.model)
    }
   getModel()
  {
      return this.model
  }

 }

  class BMW extends  Car{
      constructor(model, color){
        super(model);
         this.color = color
     }
     printModel(){
         console.log(super.getModel(), this.color)
     }
}

If parent class method needs to be used alongside with child class method, this means class design went wrong, overriding parent method was a mistake. 如果需要将父类方法与子类方法一起使用,则意味着类设计出错,覆盖父方法是一个错误。

It could be: 它可能是:

class Car{
    ...
    printGenericModel(){
        console.log(this.model)
    }
}

class BMW extends Car{
    ...
    printModel(){
        console.log(this.model, this.color)
    }
}

Or in case parent class can't be refactored: 或者如果父类无法重构:

class Car{
    ...
    printModel(){
        console.log(this.model)
    }
}

class BMW extends Car{
    ...
    get printGenericModel(){
        return super.printModel;
    }
    printModel(){
        console.log(this.model, this.color)
    }
}

Both methods are available as printGenericModel and printModel on BMW instance. 这两种方法在BMW实例上都可以作为printGenericModelprintModel使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM