在 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); // 動物
複製代碼
既然實例屬性能夠直接在類中直接定義,那靜態屬性也能夠這樣函數
// es65.js
class Animal {
static name = '動物';
constructor() {
// ...
}
}
let animal = new Animal();
console.log(Animal.name); // 動物
console.log(animal.name); // undefined
複製代碼
新增了顯眼並不新鮮的修飾符 public
、private
、protected
和 readonly
。post
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);
複製代碼
從例子中可看到ui
name
能在實例中使用;name
和 age
能在子類中使用;注: 基類的構造函數使用
this
的屬性以前必須調用super()
,這是 Typescript 的一項要求。this
不被實例化,只給基類使用。可用關鍵字 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
中上不存在;