来自typescript manual

时间:2015-06-27 23:49:52

标签: class oop object inheritance typescript1.4

typescript manual阅读示例:

class Animal {
    name:string;
    constructor(theName: string) { this.name = theName; }
    move(meters: number = 0) {
        alert(this.name + " moved " + meters + "m.");
    }
}

class Snake extends Animal {
    constructor(name: string) { super(name); }
    move(meters = 5) {
        alert("Slithering...");
        super.move(meters);
    }
}

class Horse extends Animal {
    constructor(name: string) { super(name); }
    move(meters = 45) {
        alert("Galloping...");
        super.move(meters);
    }
}

var sam = new Snake("Sammy the Python");
var tom: Animal = new Horse("Tommy the Palomino");

sam.move();
tom.move(34);

问题在于var tom: Animal = new Horse("Tommy the Palomino");行:

  • 据我所知,tom是一个Animal,其属性为Horse。是对的吗?

  • 这样做有什么意义?不要声明为var tom: Horse = ...

  • 只有一个版本可以让他有机会降级/更改/演变为Snake或任何其他Animal。我是对的吗?

  • ......或许这只是一个错字?

1 个答案:

答案 0 :(得分:3)

在上面的示例中,Animal是{{>>超类(也称为基类父类Horse 1}}和Snake。相应地,HorseSnakeAnimal子类派生类)。

声明子类时:

class Snake extends Animal
...
class Horse extends Animal

您告诉编译器,每个Snake和每个Horse实际上都是Animal。这使Animal成为" world"中更广泛的类别。该计划。 SnakeHorse继承 Animal的属性,但他们可以更改它们(和/或添加一些自己的属性)以更多专门

  • tom的声明告诉编译器该变量将接受任何Animal。正如我们之前看到的,HorseAnimal,因此编译器允许它通过。

  • 因此,它们说明了这样一个事实:每当任何表达式中需要超类的成员时,任何子类的一个成员都是可接受的。这称为协方差

  • 从字面意义上讲,没有进化或转变。这条线

    tom: Animal = new Horse("Tommy the Palomino");

    首先导致创建一个新的Horse对象。然后将该对象分配给变量tom,但此赋值确实更改对象的属性。如果您运行该示例,则会发现调用horse.move()实际上调用了方法Horse的{​​{1}}版本,该版本会报告" Palmyino移动的Tommy 45米"

    move分配给Horse的唯一明显的副作用是,最常见类型的变量不会知道{{1}的任何特定属性}。它只知道所有Animal的共同点。让我们说Horse就像这样声明:

    Animal

    您无法拨打Horse。如果您愿意,您需要对class Horse extends Animal { constructor(name: string) { super(name); } move(meters = 45) { //... } swat_fly() { /* ... */ } } 进行类型转换(例如:tom.swat_fly())或将其声明为tom而不是(<Horse>tom).swat_fly()。但我重申:对象的属性不会更改为超类。

  • 所以不,它不是一个错字:)