访问基类成员

Jaa*_*aap 106 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)
Run Code Online (Sandbox Code Playgroud)

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

有任何想法吗?

Fen*_*ton 163

工作实例.以下注释.

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);
Run Code Online (Sandbox Code Playgroud)
  1. 您无需手动将名称分配给公共变量.public name在构造函数定义中使用为您执行此操作.

  2. 您不需要super(name)从专门的类调用.

  3. 使用this.name作品.

使用注意事项super.

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

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

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

  • 谢谢Steve Fenton.我也偶然发现了类似的讨论:https://typescript.codeplex.com/discussions/418349.似乎是语言的不平衡; 我的猜测是决定保持发出的JavaScript简单,而不是"解决方法"辅助方法来弥补JavaScript支持的不足. (3认同)

Wil*_*een 11

您使用的关键字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.
Run Code Online (Sandbox Code Playgroud)

解释:

  1. 第一个记录动态值,其super.name后面是静态字符串值"is Galloping..."。关键字this引用对象的“原型链”tom,而不是对象tom自身。因为我们在 上添加了 name 属性Animal.prototype,所以 horse 将被输出。

  2. 第二条日志输出this.namethis关键字指的是 tom 对象本身。

  3. 第三条日志是使用moveAnimal 基类的方法记录的。此方法是从 Horse 类 move 方法调用的,语法如下super.move(45);。在这种情况下使用关键字将在原型链上super查找Animal 原型上的方法。move

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