{%hackmd BJrTq20hE %} ###### tags: `TypeScript` # TypeScript Class的implements、abstract、private... ## 什麼是Class 簡單的來說class是一種函式與資料的撰寫方式,不過class不會直接使用而是做為藍圖。 範例如下 constructor代表先做一些什麼事情。 ```javascript= class add { constructor(number) { this.number = number } pluse(num){ return this.number + num } } const action = new add(55) console.log(action.pluse(1))//56 ``` ## implements class與interface的應用簡單的來說就是先定義class內應該又有什麼資料與資料類型、方法以及有沒有return與return的資料 下面的範例就是interface先寫好裡面應該要有的資料與資料類型,還有方法,在class的userDat使用了implements UserDateInterface後只要缺少interface UserDateInterface的內容就會報錯。 ```javascript= interface UserDateInterface { name: string age: number id: number checkedId:(id:number)=> void checkedUser:(name:string)=> boolean } class userData implements UserDateInterface{ name: string age: number id: number // 額外的資料是可以另外加上的不會報錯 status:boolean checkedId(){} checkedUser(){ return true } // 額外的方法是可以另外加上的不會報錯 checkAge(){} } ``` ## extends 簡單的來說就是繼承類別, ```javascript= interface LifeInterface{ name:string breath:()=>void run:()=>void } class Life implements LifeInterface{ constructor(name:string){ this.name = name; } name:string breath(){ console.log('breath') } run(){ console.log('run') } } class Dog extends Life{} const dondon = new Dog("dondon") dondon.breath() dondon.run() ``` ## 所繼承的class方法可以用相同的函示名稱蓋掉 ```javascript= interface LifeInterface{ name:string breath:()=>void run:()=>void } class Life implements LifeInterface{ constructor(name:string){ this.name = name; } name:string breath(){ console.log('breath') } run(){ console.log('run') } } class Dog extends Life{ breath(){ console.log('DOG breath') } run(){ console.log('DOG run') } } const dondon = new Dog("dondon") dondon.breath() dondon.run() console.log(dondon.name) ``` ## super() 可以呼叫用相同名子蓋掉的繼承函式 ```javascript= interface LifeInterface{ name:string breath:()=>void run:()=>void } class Life implements LifeInterface{ constructor(name:string){ this.name = name; } name:string breath(){ console.log('breath') } run(){ console.log('run') } } class Dog extends Life{ breath(){ console.log('DOG breath') // 加入super.breath()就可以呼叫上一層的class方法 super.breath() } run(){ console.log('DOG run') super.run() } } const dondon = new Dog("dondon") dondon.breath() dondon.run() console.log(dondon.name) ``` ## abstract 與interface類似不過,interface內部不能執行函式而abstract可以執行函式 不過abstract不是一般的class不可以用new不然會報錯,已知只能繼承 在需要實作的函數前加上abstract ```javascript= abstract class Life { name:string breath(){ console.log('breath') } // 與interface相比少了箭頭 abstract run():void } class Dog extends Life{ run(){ console.log('run') } } const dondon = new Dog() dondon.run() ``` ## TypeScript Class成員權限,公開 不公開 受保護 ### public 不特別寫的話預設就是public ```javascript= class UserInfo { public name: string = 'Jack' } ``` ### private private在開發的時候可以避免變數被讀取或是寫入,即使是繼承或是創建一個實體也無法取得該變數。 但是在一般產品的JS環境下沒用,因為最後還是編譯成JS ```javascript= class UserInfo { private name: string = 'Jack' } 創建實體 const jack = new UserInfo() console.log(jack.name) 繼承 class otherUser extends UserInfo {} const jack = new otherUser() console.log(jack.name) ``` ![](https://i.imgur.com/Q8zvtsq.png) #### 讓別人也可以讀到private變數的方法 在class中另外寫方法return出變數 ```javascript= class UserInfo { private name: string = 'Jack' getName(){ return this.name } } const jack = new UserInfo() console.log(jack.getName()) ``` ### pritected 與private相似不過差別在於protected可以讓繼承的class使用該變數 ```javascript= class UserInfo { protected name: string = 'Jack' } class otherUser extends UserInfo { getName(){ return this.name } } const jack = new otherUser() console.log(jack.getName()) // 不過一樣在new實體的時候直接取得.name一樣會報錯 // console.log(jack.name) ``` ![](https://i.imgur.com/R3OU19Q.png) ## JS原生私有化變數的方法 JS的原生私有變數寫法 TSconfig target要記得設定為 ES6 這個私有化設定在產品端也適用 只需要在變數前面加上#,記得使用的時候也要加# ```javascript= class UserInfo { #name: string = 'Jack' getName(){ return this.#name } } ``` ## TypeScript Class static static修飾詞簡單的來說就是不用創造一個實體也能夠讀取與寫入變數或是使用函式。 用static宣告的變數在同一個class下會共用 用static所宣告的函式只能用static宣告的變數。 ```javascript= class Bank { static balance: number = 10000 static takeOutMoney(num:number): string { this.balance = this.balance - num return `提款${num}剩餘存款${this.balance}` } static checkOutMoney(): number{ return this.balance } } console.log(Bank.takeOutMoney(100))//提款100剩餘存款9900 console.log(Bank.checkOutMoney)//9900 ``` ### 也可以在static前面加入private轉為私有變數 私有變數需要使用原class內的方法return出來 ```javascript=// class Bank { private static balance: number = 10000 static takeOutMoney(num:number): string { return `提款${num}剩餘存款${this.balance}` } static checkOutMoney(): number{ return this.balance } } // 會報錯 console.log(Bank.balance) ``` ![](https://i.imgur.com/9bg85xZ.png) ### static的共用變數 以下的例子就是共用變數balance,不用new是因為如果是用new的話就會變成獨立的class ```javascript= class Bank { static balance: number = 10000 static takeOutMoney(num:number): string { this.balance = this.balance - num return `提款${num}剩餘存款${this.balance}` } static checkOutMoney(): number{ return this.balance } } function bankAtakOutMoney(num:number){ const money = Bank.takeOutMoney(num) console.log(money) } function bankBtakOutMoney(num:number){ const money = Bank.takeOutMoney(num) console.log(money) } bankAtakOutMoney(1000)//提款1000剩餘存款9000 bankBtakOutMoney(5000)//提款5000剩餘存款4000 ```