昨天簡單介紹了 interface,也舉了一個如何正確使用 interface 的情境
今天先稍微回顧一下昨天的例子
再來會記錄一下關於 interface 的其他行為
今日大綱:
implements
先來回顧一下昨天的範例
interface Attackable {
attack(): string;
}
const godMonster = {
name: 'godzilla',
year: 1954,
canFly: true,
attack(): string {
return `${this.name} attack!!!`
}
}
const player1 = {
name: 'Victor',
hp: 100,
skill: 'fire ball',
attack(): string {
return `${this.name} use ${this.skill}!!`
}
}
const printAttack = (target: Attackable) => {
console.log(target.attack())
}
printAttack(godMonster)
printAttack(player1)
在昨天的範例中,interface Attackable
制定了 可攻擊的
這個語意的介面,只要滿足他的條件,都可以被 printAttack()
方法當作合法的參數
將範例簡化一下
interface 定義的目的應該要明確,這樣才可以給非常不同的物件實作,達到重用程式碼的目的
補充的東西通常是沒有記在我原本的筆記上,在寫鐵人賽時想說要一並記錄方便給未來的自己看
implements
(重要,先簡單提及)語法:?:
在定義屬性時的冒號前面加上一個 ?
,該屬性就會變成可選屬性
下面將 interface Attackable
多了一個可選的 mp
屬性
就算參數 godMonster
沒有滿足也不會報錯
interface Attackable {
mp?: number;
attack(): string;
}
const godMonster = { // 怪獸物件
name: 'godzilla',
year: 1954,
canFly: true,
attack(): string {
return `${this.name} attack!!!`
}
}
const printAttack = (target: Attackable) => {
console.log(target.attack())
}
printAttack(godMonster)
這樣的好處是可以提醒其他開發者,可能會有這個屬性傳入,並先做預先處理
const printAttack = (target: Attackable) => {
console.log(target.attack())
if (target.mp) {
console.log(`cost mp ${target.mp} !!`)
}
}
語法: 前綴 readonly
在定義屬性時,在屬性前綴加上 readonly
,便可以將該屬性標為唯讀屬性
原本在定義物件時,滿足 interface 的物件裡面的屬性只要類別正確就好,值一樣可以再做更換,但標為唯讀屬性的話,該屬性賦值完之後值就不可以再做變動
interface Monster {
name: string;
hp: number;
mp: number;
attack(): string;
}
const motherMonster: Monster = {
name: 'Mothra',
hp: 300,
mp: 1000,
attack(): string {
return `${this.name} attack!!`
}
}
motherMonster.name = 'Mecha Mothra';
用了 readonly
定義屬性,那該屬性就不能再做變更
implements
Class 會用 implements
語法表示要實作的 interface,並且滿足 interface 定義的所有屬性
interface MonsterInterface {
name: string;
hp: number;
mp: number;
attack(): string;
}
class Monster implements MonsterInterface {
name: string;
hp: number;
mp: number;
attack(): string {
return `${this.name} attack!!`
}
constructor(name: string, hp: number, mp: number) {
this.name = name
this.hp = hp;
this.mp = mp;
}
}
一樣,如果有缺少屬性,不滿足 interface 就會報錯
這邊只是一個簡單的 Class 範例,如同昨天一開始所說
在 TypeScript 中,最重要的就是 Interfaces 和 Class 的協作
我們後面會開始講 Class 是什麼,但是 Class 的教學我也找了很多,完全不懂時開始看真的會覺得霧煞煞,實戰中學習才是最快能理解 Class 的方式