在 ES6 以前是沒有類這個概念的,都是經過構造函數來實現同等效果的,繼承的實現經過原型鏈。javascript
Typescript 除了實現 ES6 類 class 的功能外還有其餘特性。一塊兒看看。java
new
生成實現;ES6 咱們都很熟悉。使用 new
生成實例,會自動調用構造函數,而構造函數用 constructor
定義。git
// es6.js class Animal { constructor(name) { this.name = name; } showName() { return `我是${this.name}` } } let animal = new Animal('動物'); console.log(animal.showName()); // 我是動物 複製代碼
派生類使用 extends
實現繼承,用 super
來執行基類的構造函數。es6
// es6.js class Cat extends Animal { // constructor 沒有本身的屬性,可不寫 constructor(name) { super(name); } showName() { return `我是一隻${this.name}` } } let cat = new Cat('貓'); console.log(cat.showName()); // 我是一隻貓 複製代碼
// es62.js class Animal { constructor(name) { this.name = name; } get newName() { return `獲取: ${this.name}`; } set newName(value) { this.name = `新的${value}` } } let animal = new Animal('動物'); animal.newName = '大動物'; console.log(animal.newName); 複製代碼
就是使用 static
定義方法,僅供本身使用,因此無需實例化,實例不能調用。github
// es63.js class Animal { static isAnimal(animal) { return animal instanceof Animal; } } let animal = new Animal('動物'); console.log(Animal.isAnimal(animal)); // true console.log(animal.isAnimal(animal)); // TypeError: animal.isAnimal is not a function 複製代碼
ES6 中實例屬性都是在構造函數 construction
中定義,在 ES7 中直接在類裏面寫就能夠了。typescript
// es64.js class Animal { name = '動物'; constructor() { // ... } } let animal = new Animal(); console.log(animal.name); // 動物 複製代碼
既然實例屬性能夠直接在類中直接定義,那靜態屬性也能夠這樣markdown
// es65.js class Animal { static name = '動物'; constructor() { // ... } } let animal = new Animal(); console.log(Animal.name); // 動物 console.log(animal.name); // undefined 複製代碼
新增了顯眼並不新鮮的修飾符 public
、private
、protected
和 readonly
。函數
public
所修飾的屬性和方法是公共的,任意使用;private
所修飾的屬性和方法是私有的,僅供類自身使用;protected
所修飾的屬性和方法是受保護的,僅供類自身和子類使用;readonly
所修飾的屬性是隻讀的,必須在聲明時或構造函數裏被初始化;// class.ts class Star { public name: string = 'pr'; protected age: number = 18; private weight: number = 90; readonly gender: string = '女'; public constructor(name: string, age: number, weight: number, gender: string) { this.name = name; this.age = age; this.weight = weight; this.gender = gender; } } class ChinaStar extends Star { constructor(name: string, age: number, weight: number, gender: string) { super(name, age, weight, gender); } showName(){ return `我是${this.name}` } showAge(){ return `我實際年齡${this.age}` } showWeight(){ return `個人體重${this.weight}` } showGender(){ return `個人性別${this.gender}` } } let pr = new ChinaStar('pr', 30, 120, '男'); pr.name = '江湖再見'; pr.age = 18; pr.weight = 100; pr.gender = '女'; console.log(pr.name); console.log(pr.age); console.log(pr.weight); console.log(pr.gender); console.log(pr.showName()); console.log(pr.showAge()); console.log(pr.showWeight()); console.log(pr.showGender()); // 0.0.9/class.ts:29:28 - error TS2341: Property 'weight' is private and only accessible within class 'Star'. // 29 return `個人體重${this.weight}` // 0.0.9/class.ts:39:4 - error TS2445: Property 'age' is protected and only accessible within class 'Star' and its subclasses. // 39 pr.age = 18; // 0.0.9/class.ts:40:4 - error TS2341: Property 'weight' is private and only accessible within class 'Star'. // 40 pr.weight = 100; // 0.0.9/class.ts:41:4 - error TS2540: Cannot assign to 'gender' because it is a read-only property. // 41 pr.gender = '女'; // 0.0.9/class.ts:44:16 - error TS2445: Property 'age' is protected and only accessible within class 'Star' and its subclasses. // 44 console.log(pr.age); // 0.0.9/class.ts:45:16 - error TS2341: Property 'weight' is private and only accessible within class 'Star'. // 45 console.log(pr.weight); 複製代碼
從例子中可看到oop
name
能在實例中使用;name
和 age
能在子類中使用;注: 基類的構造函數使用
this
的屬性以前必須調用super()
,這是 Typescript 的一項要求。post
不被實例化,只給基類使用。可用關鍵字 Abstract
定義抽象類和其內部定義的抽象方法。不一樣於接口,抽象類能夠包含成員的實現細節。
// abstract.ts abstract class Animal2 { abstract say(): void; move(): void{ console.log('移動'); } } 複製代碼
抽象類中的抽象方法不含具體實現(這點和接口很類似,都定義了方法簽名不含方法體),但必須在派生類中實現。
// abstract2.ts // 抽象類 abstract class AbstractPerson { constructor(public name: string, public age: number, public weight: number) { } showName(): string { return `個人名字是${this.name}`; } abstract showAge(): void; } // 基類 class Person extends AbstractPerson { constructor(name: string, age: number, weight: number) { super(name, age, weight); } showAge(): void { console.log(`個人年齡${this.age}`) } showWeight(): void { console.log(`個人體重${this.weight}`) } } let person1: AbstractPerson; let person2: AbstractPerson; person1 = new AbstractPerson('pr', 30, 110); person2 = new Person('pr', 30, 110); console.log(person2.showName()); person2.showAge(); person2.showWeight(); // 0.0.9/abstract2.ts:29:11 - error TS2511: Cannot create an instance of an abstract class. // 29 person1 = new AbstractPerson('pr', 30, 110); // 0.0.9/abstract2.ts:34:9 - error TS2339: Property 'showWeight' does not exist on type 'AbstractPerson'. // 34 person2.showWeight(); 複製代碼
showWeight
在抽象類 AbstractPerson
中上不存在;