Inheritance TypeScript:演练:固有性

Inheritance TypeScript:演练:固有性,inheritance,typescript,Inheritance,Typescript,上有一个关于内在的穿行。代码稍加修改,变得更加友好 class Animal { constructor(public name: string) { } move(meters: number) { console.log(this.name + " moved " + meters + "m."); } } class Snake extends Animal { constructor(name: string) { super(name)

上有一个关于内在的穿行。代码稍加修改,变得更加友好

class Animal {
    constructor(public name: string) { }
    move(meters: number) {
        console.log(this.name + " moved " + meters + "m.");
    }
}

class Snake extends Animal {
    constructor(name: string) { super(name); }
    move() {
        console.log("Slithering...");
        super.move(5);
    }
}

class Horse extends Animal {
    constructor(name: string) { super(name); }
    move() {
        console.log("Galloping...");
        super.move(45);
    }
}

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

sam.move();
tom.move(11);
第二个对象是动物

var tom: Animal = new Horse("Tommy the Palomino");
tom.move(11);
现在作为C#开发者,我希望看到这样的结果

Slithering...
Sammy the Python moved 5m.
Tommy the Palomino moved 11m.
所以不应该调用move方法from Horse。我怎么会看到不一样的东西

Slithering...
Sammy the Python moved 5m.
Galloping...
Tommy the Palomino moved 45m.
因为它似乎忽略了以下参数“11”:

并且是从派生类运行方法

关于这一点,我有两个问题

  • 为什么会发生这种情况,或者这可能是一个bug
  • 如果它的目的是如何从Animal类调用方法,前提是我不想这样创建Animal对象

    var tom: Animal = new Animal ("Tommy the Palomino");
    
  • 为什么会发生这种情况,或者这可能是一个bug
  • 你说得对。这在类型脚本中是不同的

    在执行以下操作时:

    (new MyClass()).overriddenMethod();
    
    无论发生什么情况,都将调用MyClass中定义的方法

    这是因为(在javascript中)不存在重写方法的情况;实际上,它将被取代

    例如:

    类动物{
    move(meters:number){console.log(“Moved”+meters+“m.”;}
    }
    蛇类动物{
    move(){super.move(5);}
    }
    
    它编译为(为了简单起见,删除了_extends实现):

    Snake
    上的
    move
    将取代
    Animal
    上的
    move
    实现。在内部,您可以使用
    super
    调用父方法,但在类之外永远不会进行到父类的转换

    因此,我们有能力:

    var foo: Animal = new Snake("Some awesome snake");
    
    简单地说,
    Snake
    具有相同的“接口”(也就是说,它看起来有点像
    Animal
    ),但是如果重写父类上的某个方法,那么可以说,您永远无法将其取回。当转换到javascript时,获得这种多态性的能力就消失了,在javascript中,所有类型的知识都被丢弃了

  • 如果是预期行为,如何从Animal类调用方法 前提是我不想创建这样的动物对象
  • 您可以这样做:

    class Animal {
        move(meters: number) { console.log("Moved " + meters + "m."); }
    }
    
    class Snake extends Animal {
    
        move(meters?: number) {
            super.move(meters != null ? meters : 5);
        }
    }
    
    甚至:

    class Animal {
        move(meters: number) { console.log("Moved " + meters + "m."); }
    }
    
    class Snake extends Animal {
    
        move();
        move(meters: number);
        move(someRandomThing: MyNiceObject);
        move(meters: number, someRandomThing: MyNiceObject);
        move() {
            var args = arguments;
            if (args.length == 0) {
                super.move(3);
            }
            else if (args.length == 2) {
                // Do something related to..
                // move(meters: number, someRandomThing: MyNiceObject);
            }
            else {
                if (typeof(args[0]) === "number") {
                    // move(meters: number);
                } else {
                    // move(someRandomThing: MyNiceObject);
                }
            }
        }
    }
    
    所以。。从经典的面向对象方法来看,这可能是限制性的(我来自C,C++等我自己)。但是我很少再注意到它了,它仍然在一周中的任何一天都是纯javascript

    class Animal {
        move(meters: number) { console.log("Moved " + meters + "m."); }
    }
    
    class Snake extends Animal {
    
        move(meters?: number) {
            super.move(meters != null ? meters : 5);
        }
    }
    
    class Animal {
        move(meters: number) { console.log("Moved " + meters + "m."); }
    }
    
    class Snake extends Animal {
    
        move();
        move(meters: number);
        move(someRandomThing: MyNiceObject);
        move(meters: number, someRandomThing: MyNiceObject);
        move() {
            var args = arguments;
            if (args.length == 0) {
                super.move(3);
            }
            else if (args.length == 2) {
                // Do something related to..
                // move(meters: number, someRandomThing: MyNiceObject);
            }
            else {
                if (typeof(args[0]) === "number") {
                    // move(meters: number);
                } else {
                    // move(someRandomThing: MyNiceObject);
                }
            }
        }
    }