子类变量引用父类对象

时间:2018-04-30 17:46:59

标签: typescript ecmascript-6 polymorphism

下面是使用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

对于变量d,TypeScript支持结构类型,并且类型Dog在覆盖后具有Mammal具有的至少属性(类似)。因此,变量d仍然可以指向Mammal类型对象,直到在Dog类型中添加了另一个属性。

在TypeScript中,如何避免这些陷阱?

1 个答案:

答案 0 :(得分:3)

没有办法避免它。结构类型是TypeScript中与JavaScript和JSON互操作的需要。我们需要支付一点费用,以及TypeScript目的的一个后果,即向JavaScript添加类型,同时仍然与它完全兼容,特别是现有的代码库。

在您的示例中,避免它的唯一方法是向Dog添加Mammal没有的内容,或者可能使Mammal成为抽象类,所以它不能直接实例化。在这种情况下,它是合乎逻辑的,因为您可以创建新的DogCatHorse ...但不只是新的Mammal

正如Titian和Estus指出的那样,如果你不想让Mammal抽象出来并想要区分课程,即使你并不真的想要添加任何额外的东西,将添加一个不相关的私有属性,在运行时没有(几乎)任何影响:

private isDog: undefined;