如何正确覆盖打字稿中的方法?

How to properly override a method in typescript?

提问人:Gandalf 提问时间:3/12/2021 最后编辑:Gandalf 更新时间:3/12/2021 访问量:2016

问:

为什么方法中是空的?this.fullNameshow()

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

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

TypeScript 继承 这个

评论

0赞 Arfat Binkileb 3/12/2021
请详细说明哪种语言,输出
0赞 Gandalf 3/12/2021
我已经在标签中指定了语言。并且输出已在代码中注释。@ArfatBinkileb
1赞 Psidom 3/12/2021
我对此的看法是,您不能在 super 调用中更改子属性,因为到 super 时,子属性还不存在。
0赞 Psidom 3/12/2021
所以基本上初始化发生在调用之后,这覆盖了你在 .fullNamesuperfullNamemakeSir

答:

0赞 Arfat Binkileb 3/12/2021 #1
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();

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

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

输出:

#########Man 
Man 
PERSON
2赞 y2bd 3/12/2021 #2

super()在构造像 your 这样的派生类时,总是首先调用的。这包括在您执行的任何变量初始化之前,例如 .因此,当 u 被调用并设置为一个好的值时,紧接着你的空字符串赋值就会启动并清除其值。Manprotected fullName = ''Man.makeSirfullName

避免这种延迟覆盖的一种方法是不为 设置初始值: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;

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

评论

0赞 Linda Paiste 3/12/2021
这真的很有趣!我不会想到变量初始化会在构造函数调用之后发生。但是当我更多地考虑它时,它确实是有道理的,因为它是由 触发的。makeSirsuper()
1赞 y2bd 3/12/2021
当我考虑 JS 如何处理对象的原型性质时,这是有道理的,但 IMO 如果您来自 C# 或 Java 等其他 OOP 语言,它仍然令人沮丧。