classAnimal { name;constructor(name) {this.name = name; }sayHi() {return`My name is ${this.name}`; }}let a =newAnimal('Jack');console.log(a.sayHi()); // My name is Jack
类的继承
使用 extends 关键字实现继承,子类中使用 super 关键字来调用父类的构造函数和方法。
classCatextendsAnimal {constructor(name) {super(name); // 调用父类的 constructor(name)console.log(this.name); }sayHi() {return'Meow, '+super.sayHi(); // 调用父类的 sayHi() }}let c =newCat('Tom'); // Tomconsole.log(c.sayHi()); // Meow, My name is Tom
classAnimal {staticisAnimal(a) {return a instanceofAnimal; }}let a =newAnimal('Jack');Animal.isAnimal(a); // truea.isAnimal(a); // TypeError: a.isAnimal is not a function
classAnimal {public name;publicconstructor(name) {this.name = name; }}let a =newAnimal('Jack');console.log(a.name); // Jacka.name ='Tom';console.log(a.name); // Tom
上面的例子中,name 被设置为了 public,所以直接访问实例的 name 属性是允许的。
很多时候,我们希望有的属性是无法直接存取的,这时候就可以用 private 了:
classAnimal {private name;publicconstructor(name) {this.name = name; }}let a =newAnimal('Jack');console.log(a.name);a.name ='Tom';// index.ts(9,13): error TS2341: Property 'name' is private and only accessible within class 'Animal'.// index.ts(10,1): error TS2341: Property 'name' is private and only accessible within class 'Animal'.
var Animal = (function () {functionAnimal(name) {this.name = name; }return Animal;})();var a =newAnimal('Jack');console.log(a.name);a.name ='Tom';
使用 private 修饰的属性或方法,在子类中也是不允许访问的:
classAnimal {private name;publicconstructor(name) {this.name = name; }}classCatextendsAnimal {constructor(name) {super(name);console.log(this.name); }}// index.ts(11,17): error TS2341: Property 'name' is private and only accessible within class 'Animal'.
classAnimal {public name;privateconstructor(name) {this.name = name; }}classCatextendsAnimal {constructor(name) {super(name); }}let a =newAnimal('Jack');// index.ts(7,19): TS2675: Cannot extend a class 'Animal'. Class constructor is marked as private.// index.ts(13,9): TS2673: Constructor of class 'Animal' is private and only accessible within the class declaration.
当构造函数修饰为 protected 时,该类只允许被继承:
classAnimal {public name;protectedconstructor(name) {this.name = name; }}classCatextendsAnimal {constructor(name) {super(name); }}let a =newAnimal('Jack');// index.ts(13,9): TS2674: Constructor of class 'Animal' is protected and only accessible within the class declaration.
classAnimal {readonly name;publicconstructor(name) {this.name = name; }}let a =newAnimal('Jack');console.log(a.name); // Jacka.name ='Tom';// index.ts(10,3): TS2540: Cannot assign to 'name' because it is a read-only property.
abstractclassAnimal {public name;publicconstructor(name) {this.name = name; }publicabstractsayHi();}let a =newAnimal('Jack');// index.ts(9,11): error TS2511: Cannot create an instance of the abstract class 'Animal'.
abstractclassAnimal {public name;publicconstructor(name) {this.name = name; }publicabstractsayHi();}classCatextendsAnimal {publiceat() {console.log(`${this.name} is eating.`); }}let cat =newCat('Tom');// index.ts(9,7): error TS2515: Non-abstract class 'Cat' does not implement inherited abstract member 'sayHi' from class 'Animal'.
var __extends = (this&&this.__extends) ||function (d, b) {for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];function__() {this.constructor= d; }d.prototype= b ===null?Object.create(b) : ((__.prototype=b.prototype),new__()); };var Animal = (function () {functionAnimal(name) {this.name = name; }return Animal;})();var Cat = (function (_super) {__extends(Cat, _super);functionCat() {_super.apply(this, arguments); }Cat.prototype.sayHi=function () {console.log('Meow, My name is '+this.name); };return Cat;})(Animal);var cat =newCat('Tom');
类的类型
给类加上 TypeScript 的类型很简单,与接口类似:
classAnimal { name:string;constructor(name:string) {this.name = name; }sayHi():string {return`My name is ${this.name}`; }}let a:Animal=newAnimal('Jack');console.log(a.sayHi()); // My name is Jack