nik
nik

Reputation: 303

inheritance example from typescript manual

Reading example from 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);

The question is about the line var tom: Animal = new Horse("Tommy the Palomino");:

Upvotes: 2

Views: 1530

Answers (1)

Alexander Feterman
Alexander Feterman

Reputation: 131

In the example above, Animal is a superclass (also called base class or parent class) of both Horse and Snake. Correspondingly, Horse and Snake are subclasses (derived classes) of Animal.

When you declare the subclasses:

class Snake extends Animal
...
class Horse extends Animal

You're telling the compiler that any every Snake and every Horse is in fact, an Animal as well. This makes Animal the broader category in the "world" of the program. Snake and Horse will inherit the properties of Animal, but they can change them (and/or add a few of their own) to be more specialized.

  • tom's declaration tells the compiler that the variable will accept any Animal. As we saw earlier, a Horse is an Animal, so the compiler lets it pass.

  • Hence, they're illustrating the fact that whenever a member of the superclass is expected in any expression, one member of any of its subclasses is acceptable. This is called covariance.

  • In the most literal sense, there is no evolving or devolving. The line

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

    first causes a new Horse object to be created. The object is then assigned to the variable tom, but this assignment does not change the properties of the object. If you ran the example, you'd see that the call horse.move() actually calls the Horse version of the method move, which would report that "Tommy the Palomino moved 45m".

    The only discernible side effect of assigning a Horse to an Animal is that the variable, being of the most general type, wouldn't know of any specialized properties of Horse. It only knows what all Animals have in common. Let's say Horse was declared like this:

    class Horse extends Animal {
        constructor(name: string) { super(name); }
        move(meters = 45) {
            //...
        }
        swat_fly() { /* ... */ }
    }
    

    You wouldn't be able to call tom.swat_fly(). If you wanted to, you either need to typecast tom (like this: (<Horse>tom).swat_fly()) or declare it as a Horse instead of as an Animal. But I reiterate: the object's properties are not changed to the superclass's.

  • So no, it's not a typo :)

Upvotes: 3

Related Questions