我喜欢杰夫和邓肯已经提出的很多。不过,让我再展示一个选项。
abstract class Animal {
constructor(public name: string) {
console.log(this.name);
}
}
class Snake extends Animal { }
let someSnake = new Snake("Snakeeeey!");
注意这里的几件事情。
Animal
类似乎确实是一个抽象的概念。您可以选择将其标记为abstract
或将其定义为interface
,但后者不会让您有任何实现(包括构造函数)。
- TypeScript允许我们定义从构造函数初始化的字段。在公共财产的情况下,我们只需编写
constructor(public name: string)
。
Snake
类不明确明确定义了一个构造函数。然而,在创建蛇物品时,消费者必须提供Animal
类别所要求的name
参数。
在Jeff的代码中,Snake类的name
的默认值是constructor(name: string = 'BeatSSS') { super(name); }
。我不知道你的具体用例。如果没有任何有意义的默认名称为蛇,我会避免完全声明这样的构造函数。
邓肯正确地解释说,调用super()
并非天生就是错误的。而且,这是必要的。
当通过构造函数创建Snake
类型的对象时,必须首先完成父(Animal
)的构造函数。因此,Animal
构造函数无法“查看”子项(Snake
)构造函数中发生的字段初始化的影响。由于构造函数调用的顺序,这是不可能的。
因此,子类型为父类构造函数传递信息的唯一选项是直接调用super(...)
。儿童construct()
super()
呼叫解决这个问题,但我需要做的每一个孩子。不是很优雅的解决方案
基本上没有完全定义子构造函数就是答案。如果您的孩子类必须具有构造函数,他们将强制您调用super()
作为the very first instruction。
在父构造上使用超时记录正确的值,但不能立即使用类的实例(beacouse超时尚未执行)。
这是一个非常糟糕的选择。首先,一般不建议在构造函数中有任何异步代码调用。
其次,如果你还做了在Animal
setTimeout(() => this.fixMyState(), 0)
构造它会导致不良的影响:对象构造后立即对象是在糟糕的状态。如果某些代码立即使用该对象会怎么样? () => this.fixMyState(), 0
甚至没有机会运行修复对象。建立后立即在良好状态中有一个对象是一条经验法则。否则,构造函数应该会出现错误throw
,这样就没有代码可以尝试对处于不良状态的对象进行操作。
当调用父构造函数时,对象尚未完全形成。它只是父母的一部分。这就是几乎所有的OOP语言的工作原理。 – 2017-10-21 18:53:36