【问题标题】:How to properly override a method in typescript?如何正确覆盖打字稿中的方法?
【发布时间】:2021-06-09 19:30:28
【问题描述】:

为什么show() 方法中的this.fullName 为空?

class Person {
  protected name: string = "";
  constructor(name: string) {
    this.makeSir(name);
  }

  makeSir(name: string) {
    this.name = "sir" + name;  
  }
}

class Man extends Person {
  protected fullName = "";
  constructor(name: string) {
    super(name);
  }

  makeSir(name: string) {
    super.makeSir(name);
    this.fullName = "***" + name;
    console.log(this.fullName);//[LOG]: "***john" 
  }

  show() {
    console.log(this.fullName);//[LOG]: "" 
  }
}


const man = new Man("john");
man.show();

我应该如何解决这个问题?

【问题讨论】:

  • 请详细说明输出是哪种语言
  • 我已经在标签中指定了语言。并且输出已在代码中进行了注释。 @ArfatBinkileb
  • 我的看法是,你不能在 super 调用中更改 children 的属性,因为到 super 时,children 的属性还不存在。
  • 所以基本上fullName 的初始化发生在super 调用之后,它会覆盖您在makeSir 中设置的fullName

标签: typescript inheritance this


【解决方案1】:

super()总是在构造像 Man 这样的派生类时首先调用。这包括在您执行的任何变量初始化之前,例如protected fullName = ''。因此,当您的 Man.makeSir 被调用并将 fullName 设置为一个合适的值时,您的空字符串分配将立即启动并清除其值。

避免这种后期覆盖的一种方法是不为fullName 设置初始值:

// give it a type because we don't give it an initial value
// use `!` syntax to hint to TypeScript that this will be initialized during the constructor
// even though TS cannot figure that out itself
protected fullName!: string;

现在,由于您从未将 fullName 设置为“初始”值,因此您永远不会覆盖 super() 调用所做的工作。

【讨论】:

  • 这真的很有趣!我不会想到变量初始化会发生在构造函数调用makeSir 之后。但是当我仔细考虑它时,它确实是有道理的,因为它是由super() 触发的。
  • 当我考虑到 JS 如何处理对象的原型性质时,这是有道理的,但如果您来自 C# 或 Java 等其他 OOP 语言,IMO 仍然令人沮丧。
【解决方案2】:
class Person  {
    
protected name: String ="";
    
    constructor(name: string){
        this.makeSir(name);
    }
    
    makeSir(name: string){
        this.name="sir"+name ;
    }
    
    test(){
        console.log("PERSON");
    }
}

class Man extends Person {
    public name: string ="";
    
    constructor(name:string){
        super(name);
        this.makeSir(name);
    }
    
    makeSir(name:string){
        this.name="####"+name;
    }
    
    test(){
        console.log("Man ")
    }
    show(){
        console.log("#####"+this.name);
    }
}

const n = new Man("Man ")
n.show();
n.test();


const m = new Person("Person");
m.test();

你只是在构造函数中调用super,而在tern中只调用超级构造函数。

如果您看到测试被正确覆盖

输出:

#########Man 
Man 
PERSON

【讨论】:

    猜你喜欢
    • 2020-12-22
    • 2020-05-26
    • 2019-06-20
    • 2018-04-10
    • 1970-01-01
    • 1970-01-01
    • 2017-10-02
    • 2016-10-08
    • 2015-09-16
    相关资源
    最近更新 更多