TypeScript 中類的理解?應用場景?


 

 

一、是什么

類(Class)是面向對象程序設計(OOP,Object-Oriented Programming)實現信息封裝的基礎

類是一種用戶定義的引用數據類型,也稱類類型

傳統的面向對象語言基本都是基於類的,JavaScript 基於原型的方式讓開發者多了很多理解成本

在 ES6 之后,JavaScript 擁有了 class 關鍵字,雖然本質依然是構造函數,但是使用起來已經方便了許多

但是JavaScript 的class依然有一些特性還沒有加入,比如修飾符和抽象類

TypeScript 的 class  支持面向對象的所有特性,比如 類、接口等

二、使用方式

定義類的關鍵字為 class,后面緊跟類名,類可以包含以下幾個模塊(類的數據成員):

  • 「字段」 :字段是類里面聲明的變量。字段表示對象的有關數據。
  • 「構造函數」:類實例化時調用,可以為類的對象分配內存。
  • 「方法」:方法為對象要執行的操作

如下例子:

class Car { 
    // 字段 
    engine:string; 
 
    // 構造函數 
    constructor(engine:string) { 
        this.engine = engine 
    }  
 
    // 方法 
    disp():void { 
        console.log("發動機為 :   "+this.engine) 
    } 
}

繼承

類的繼承使用過extends的關鍵字

class Animal {
    move(distanceInMeters: number = 0) {
        console.log(`Animal moved ${distanceInMeters}m.`);
    }
}

class Dog extends Animal {
    bark() {
        console.log('Woof! Woof!');
    }
}

const dog = new Dog();
dog.bark();
dog.move(10);
dog.bark();

Dog是一個 派生類,它派生自 Animal 基類,派生類通常被稱作子類,基類通常被稱作 超類

Dog類繼承了Animal類,因此實例dog也能夠使用Animalmove方法

同樣,類繼承后,子類可以對父類的方法重新定義,這個過程稱之為方法的重寫,通過super關鍵字是對父類的直接引用,該關鍵字可以引用父類的屬性和方法,如下:

class PrinterClass { 
   doPrint():void {
      console.log("父類的 doPrint() 方法。") 
   } 

 
class StringPrinter extends PrinterClass { 
   doPrint():void { 
      super.doPrint() // 調用父類的函數
      console.log("子類的 doPrint()方法。")
   } 
}

修飾符

可以看到,上述的形式跟ES6十分的相似,typescript在此基礎上添加了三種修飾符:

  • 公共 public:可以自由的訪問類程序里定義的成員
  • 私有 private:只能夠在該類的內部進行訪問
  • 受保護 protect:除了在該類的內部可以訪問,還可以在子類中仍然可以訪問

私有修飾符

只能夠在該類的內部進行訪問,實例對象並不能夠訪問

 

 

並且繼承該類的子類並不能訪問,如下圖所示:

 

 

受保護修飾符

跟私有修飾符很相似,實例對象同樣不能訪問受保護的屬性,如下:

圖片

有一點不同的是 protected 成員在子類中仍然可以訪問

 

 

除了上述修飾符之外,還有只讀「修飾符」

只讀修飾符

通過readonly關鍵字進行聲明,只讀屬性必須在聲明時或構造函數里被初始化,如下:

 

 

除了實例屬性之外,同樣存在靜態屬性

靜態屬性

這些屬性存在於類本身上面而不是類的實例上,通過static進行定義,訪問這些屬性需要通過 類型.靜態屬性 的這種形式訪問,如下所示:

class Square {
    static width = '100px'
}

console.log(Square.width) // 100px

上述的類都能發現一個特點就是,都能夠被實例化,在 typescript中,還存在一種抽象類

抽象類

抽象類做為其它派生類的基類使用,它們一般不會直接被實例化,不同於接口,抽象類可以包含成員的實現細節

abstract關鍵字是用於定義抽象類和在抽象類內部定義抽象方法,如下所示:

abstract class Animal {
    abstract makeSound(): void;
    move(): void {
        console.log('roaming the earch...');
    }
}

這種類並不能被實例化,通常需要我們創建子類去繼承,如下:

class Cat extends Animal {

    makeSound() {
        console.log('miao miao')
    }
}

const cat = new Cat()

cat.makeSound() // miao miao
cat.move() // roaming the earch...

三、應用場景

除了日常借助類的特性完成日常業務代碼,還可以將類(class)也可以作為接口,尤其在 React 工程中是很常用的,如下:

export default class Carousel extends React.Component<Props, State> {}

由於組件需要傳入 props 的類型 Props ,同時有需要設置默認 props 即 defaultProps,這時候更加適合使用class作為接口

先聲明一個類,這個類包含組件 props 所需的類型和初始值:

// props的類型
export default class Props {
  public children: Array<React.ReactElement<any>> | React.ReactElement<any> | never[] = []
  public speed: number = 500
  public height: number = 160
  public animation: string = 'easeInOutQuad'
  public isAuto: boolean = true
  public autoPlayInterval: number = 4500
  public afterChange: () => {}
  public beforeChange: () => {}
  public selesctedColor: string
  public showDots: boolean = true
}

當我們需要傳入 props 類型的時候直接將 Props 作為接口傳入,此時 Props 的作用就是接口,而當需要我們設置defaultProps初始值的時候,我們只需要:

public static defaultProps = new Props()

Props 的實例就是 defaultProps 的初始值,這就是 class作為接口的實際應用,我們用一個 class 起到了接口和設置初始值兩個作用,方便統一管理,減少了代碼量


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM