ts學習第六篇 介面

weixin_44478972發表於2020-12-22
// 介面
/**
 * 1.介面一方面可以在物件導向程式設計中表示為 行為的抽象, 另外可以用來描述 物件的形狀
 * 2.介面就是把一些類中共有的屬性和方法抽象出來,可以用來約束實現此介面的類
 * 3.一個類可以繼承另一個類並實現多個介面
 * 3.介面像外掛一樣是用來增強類的, 而抽象類是具體類的抽象概念
 * 4.一個類可以實現多個介面,一個介面也可以被多個類實現,但是一個類可以有多個子類,只能有一個父類
 */

export{}

//  描述物件的形狀
interface Speakable {
  name:string
  speak():void
}

let speakMan:Speakable = {
  name:'111',
  speak(){}
}



// 行為的抽象
// 同名介面可以寫多個, 型別自動合併
interface Speakable {
  speak(): void
}
interface Eatable {
  eat(): void
}

class Person implements Speakable,Eatable {
  name: string;
  speak(): void {
    throw new Error("Method not implemented.");
  }
  eat(): void {
    throw new Error("Method not implemented.");
  }
}



// 任意屬性
interface Person2 {
  readonly id: number
  name: string
  [key:string]: any  //表示任意屬性(該屬性可有可無), 如果不加這一項下面的age:10 會報錯
}

let p: Person2 = {
  id: 1,
  name: '111',
  age: 10
}



// 介面的繼承
interface Speakable2 {
  speak(): void
}
interface SpeakChinese extends Speakable2 {
  speakChinese(): void
}

class ChineseMan implements SpeakChinese {
  speakChinese(): void {
    throw new Error("Method not implemented.");
  }  
  speak(): void {
    throw new Error("Method not implemented.");
  }
}



// readonly
interface Person3 {
  readonly id: number
}

let p1: Person3 = {
  id: 1
}
// p1.id = 2  //報錯, 因為id為只讀屬性



// 函式型別介面
interface Discount {
  (price:number): number
}

const discount:Discount = (price: number): number => {
  return price * .8
}



// 可索引介面
// 對陣列和物件進行約束
interface User {
  [index: number] : string
}

let user: User = {
  0: '0',
  1: '1',
  2: '2'
}
let arr: User = ['1', '2', '3']



// 用介面約束類(見行為的抽象部分)



// 約束類的建構函式型別
class Animal {
  constructor(public name: string) {

  }
}
// 如果是修飾普通函式, 不需要加new
// 加上new之後就是用來描述建構函式型別(類的建構函式)
interface WithNameClass {
  new(name: string): any
}

function creatClass (clazz: WithNameClass, name: string){
  return new clazz(name)
}
let a = creatClass(Animal, '111')
console.log(a.name);  // 111

//React也非常重要的一個知識點
export {}

/**
 * 當我們寫一個類的時候,會得到兩個型別
 * 1.建構函式的函式型別
 * 2.類的例項型別
*/
namespace a {
  class Component {
    static myName: string = '靜態名稱屬性'
    myName: string = '例項名稱屬性'
  }

  // Component類名本身表示的是例項型別
  let c: Component = new Component
  // ts 一個型別  一個值
  // 冒號後面是型別, 等號後面是值
  let f: typeof Component = Component
}
// 編譯後變為下面:
namespace b {
  function Component() {
    this.myName = '例項名稱屬性'
  }
  Component.myName = '靜態名稱屬性'
  let f: typeof Component = Component
}



// 區分以下寫法
interface Type1 { 
  (name: string): any  //描述的是一個函式
  age: number
}

interface Type2 { 
  a: (name: string) => any  //描述的是一個物件, 物件的屬性a, 屬性值是一個函式
}

let t: any = (name: string) => {}
t.age = 10
let t1: Type1 = t
let t2: Type2 = {
  a: t1
}

抽象類和介面的區別:
待完成

相關文章