以下是使用TypeScript的语法,
interface Animal{
eat():void;
sleep():void;
}
class Mammal implements Animal{
constructor(private name:string){
console.log(this.name, "is alive");
}
eat(){
console.log("Like a mammal");
}
sleep(){
console.log("Like a mammal");
}
}
class Dog extends Mammal{
eat(){
console.log("Like a dog")
}
}
let m: Mammal = new Dog("Prisca"); // looks fine
let d: Dog = new Mammal("abomination"); // This also works
对于variable d
,TypeScript支持结构化类型,类型Dog
具有至少属性(相似)Mammal
,在覆盖后具有。因此,在类型中再添加一个属性之前,变量d
仍然可以指向Mammal
类型对象Dog
。
在TypeScript中,如何避免此类陷阱?
无法避免。TypeScript中需要结构化类型来实现与JavaScript和JSON的互操作性。这是我们必须付出的一点代价,也是TypeScript目的的结果,即在仍与JavaScript尤其是与现有代码库完全兼容的同时向JavaScript添加类型。
避免它的唯一方法,在你的榜样,是添加的东西Dog
是Mammal
没有的,或者,也许,做Mammal
一个抽象类,所以不能被直接实例化。在这种情况下,这将是合乎逻辑的,因为你可以创建一个新的Dog
,Cat
,Horse
...但不只是一个新的Mammal
。
正如Titian和Estus所指出的那样,如果您不想Mammal
抽象,并且不想真正地添加任何额外的东西,而想通过区分类的方式,一个简单的选择就是添加一个无关的私有属性。在运行时几乎没有任何影响:
private isDog: undefined;
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句