访问基类成员

时间:2012-10-29 12:14:41

标签: typescript

请参阅TypeScript站点上的playground中的继承示例:

class Animal {
    public name;
    constructor(name) { 
        this.name = name;
    }
    move(meters) {
        alert(this.name + " moved " + meters + "m.");
    }
}

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

class Horse extends Animal {
    constructor( name) { super(name); }
    move() {
        alert(super.name + " is Galloping...");
        super.move(45);
    }
}

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

sam.move()
tom.move(34)

我更改了一行代码:Horse.move()中的提醒。我想访问super.name,但只返回undefined。 IntelliSense建议我可以使用它并且TypeScript编译得很好,但它不起作用。

有什么想法吗?

2 个答案:

答案 0 :(得分:147)

工作示例。以下注释。

class Animal {
    constructor(public name) {
    }

    move(meters) {
        alert(this.name + " moved " + meters + "m.");
    }
}

class Snake extends Animal {
    move() {
        alert(this.name + " is Slithering...");
        super.move(5);
    }
}

class Horse extends Animal {
    move() {
        alert(this.name + " is Galloping...");
        super.move(45);
    }
}

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

sam.move();
tom.move(34);
  1. 您无需手动将名称指定给公共变量。在构造函数定义中使用public name可以为您执行此操作。

  2. 您无需从专业课程中拨打super(name)

  3. 使用this.name有效。

  4. 使用super的说明。

    在语言规范的section 4.9.2中有更详细的介绍。

    Animal继承的类的行为与其他语言中的行为没有什么不同。您需要指定super关键字,以避免在专用函数和基类函数之间产生混淆。例如,如果您调用了move()this.move(),那么您将处理专门的SnakeHorse函数,因此使用super.move()显式调用基类函数

    没有属性的混淆,因为它们是实例的属性。 super.namethis.name之间没有区别 - 只有this.name。否则,您可以创建一个具有不同名称的Horse,具体取决于您是在专业类还是基类中。

答案 1 :(得分:0)

您错误地使用了superthis关键字。这是它们如何工作的示例:

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

class Horse extends Animal {
    move() {
        console.log(super.name + " is Galloping...");
        console.log(this.name + " is Galloping...");
        super.move(45);
    }
}

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

Animal.prototype.name = 'horseee'; 

tom.move(34);
// Outputs:

// horseee is Galloping...
// Tommy the Palomino is Galloping...
// Tommy the Palomino moved 45m.

说明:

  1. 第一个日志输出super.name,这是指对象tom而不是对象tom自身的原型链。因为我们在Animal.prototype上添加了name属性,所以将输出horseee。
  2. 第二个日志输出this.namethis关键字引用了tom对象本身。
  3. 使用Animal基类的move方法记录第三条日志。从Horse类的移动方法中,使用语法super.move(45);调用此方法。在这种情况下使用super关键字将在Animal原型上找到的原型链上寻找一种move方法。

请记住,TS仍然在底层使用原型,并且classextends关键字只是原型继承上的语法糖。