1. 程式人生 > 實用技巧 >類和多型

類和多型

對於傳統的 JavaScript 程式我們會使用函式基於原型的繼承來建立可重用的元件,但對於熟悉使用面向物件方式的程式設計師使用這些語法就有些棘手,因為他們用的是基於類的繼承並且物件是由類構建出來的。 從 ECMAScript 2015,也就是 ES6 開始, JavaScript 程式設計師將能夠使用基於類的面向物件的方式。 使用 TypeScript,我們允許開發者現在就使用這些特性,並且編譯後的 JavaScript 可以在所有主流瀏覽器和平臺上執行,而不需要等到下個 JavaScript 版本。

基本示例

下面看一個使用類的例子:

/* 
類的基本定義與使用
*/
class Person {
//宣告屬性
// 注意: 在ts中,類中要宣告屬性,必須要提前宣告
name:string
age:number

//構造方法
constructor(name,age){
this.name = name
this.age = age
}

//一般方法
speak():void{
console.log(`我的名字是${this.name},我的年齡是${this.age}`)
}

}
//建立類的例項
const person1 = new Person('tom',19)
//呼叫例項的方法
person1.speak()

如果你使用過 C# 或 Java,你會對這種語法非常熟悉。 我們宣告一個 Person

類。這個類有 4個成員:一個叫做 name 的屬性,一個叫做 age 的屬性,一個建構函式和一個 speak 方法。

你會注意到,我們在引用任何一個類成員的時候都用了 this。 它表示我們訪問的是類的成員。

後面一行,我們使用 new 構造了 Person 類的一個例項。它會呼叫之前定義的建構函式,建立一個 Person 型別的新物件,並執行建構函式初始化它。

最後一行通過 person1 物件呼叫其 speak 方法

繼承

在 TypeScript 裡,我們可以使用常用的面向物件模式。 基於類的程式設計中一種最基本的模式是允許使用繼承來擴充套件現有的類。

看下面的例子:

class Animal {
run (distance: number) {
console.log(`動物奔跑了${distance}米`)
}
}

class Dog extends Animal {
cry () {
console.log('汪汪汪!')
}
}

const dog = new Dog()
dog.cry()
dog.run(100) // 可以呼叫從父中繼承得到的方法

這個例子展示了最基本的繼承:類從基類中繼承了屬性和方法。 這裡,Dog 是一個 派生類,它派生自 Animal 基類,通過 extends 關鍵字。 派生類通常被稱作子類,基類通常被稱作超類

因為 Dog 繼承了 Animal 的功能,因此我們可以建立一個 Dog 的例項,它能夠 cry()run()

多型

多型指同一個實體同時具有多種形式。它是面向物件程式設計(OOP)的一個重要特徵。如果一個語言只支援類而不支援多型,只能說明它是基於物件的,而不是面向物件的,

簡單的說,就是一句話:允許將子類型別的指標賦值給父類型別的指標

下面我們來看個更加複雜的例子:

//定義Animal基類
class Animal {
//宣告屬性
name:string

//構造方法
constructor(name){
this.name = name
}

//一般方法
run (distance: number) {
console.log(`動物前進了 ${distance}m`)
}
}

class Snake extends Animal{
//構造方法
constructor(name){
super(name)
}
//重寫從父類繼承過來的方法
run(distance:number){
console.log(`蛇前進了${distance}米`)
}
}

class Horse extends Animal{
//構造方法
constructor(name){
super(name)
}
//重寫從父類繼承過來的方法
run(distance:number){
console.log(`馬奔跑了${distance}米`)
}
//自己的一般方法
cry(){
console.log('hou~hou~')
}
}

// 父型別引用指向子型別的例項 ==> 多型
let tom:Animal //表示tom這個變數的值,應該是animal例項
tom = new Animal('動物')
tom = new Snake('蟒蛇')
tom.run(100)

tom = new Horse('短腿馬')
tom.run(300)

這個例子展示了一些上面沒有提到的特性。 這一次,我們使用 extends 關鍵字建立了 Animal的兩個子類:HorseSnake

與前一個例子的不同點是,派生類包含了一個建構函式,它 必須呼叫 super(),它會執行基類的建構函式。 而且,在建構函式裡訪問 this 的屬性之前,我們 一定要呼叫 super()。 這個是 TypeScript 強制執行的一條重要規則。

這個例子演示瞭如何在子類裡可以重寫父類的方法。Snake類和 Horse 類都建立了 run 方法,它們重寫了從 Animal 繼承來的 run 方法,使得 run 方法根據不同的類而具有不同的功能。注意,即使 tom 被宣告為 Animal 型別,但因為它的值是 Horse,呼叫 tom.run(34) 時,它會呼叫 Horse 裡重寫的方法。