139

请参阅 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 可以正常编译,但它不起作用。

有任何想法吗?

4

2 回答 2

209

工作示例。注释如下。

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作品。

使用注意事项super

这在语言规范的第 4.9.2 节中有更详细的介绍。

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

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

于 2012-10-29T14:37:56.327 回答
8

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

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,this 指的是对象的原型链tom,而不是对象tom自身。因为我们在 上添加了 name 属性Animal.prototype,所以会输出 horseee。
  2. 第二个日志输出this.namethis关键字是指 tom 对象本身。
  3. 第三个日志是使用moveAnimal 基类的方法记录的。此方法是从 Horse 类 move 方法中调用的,语法为super.move(45);。在此上下文中使用super关键字将move在原型链上查找在 Animal 原型上找到的方法。

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

于 2019-07-13T12:22:02.527 回答