【TypeScript 专题】之 Ts 中的类(class)
在 ES6 中,class (類)作為對象的模板被引入,可以通過 class 關(guān)鍵字定義類。它本質(zhì)仍然是函數(shù),它讓對象原型的寫法更加清晰、更像面向?qū)ο缶幊痰恼Z法。
在 TypeScript 中,除了實(shí)現(xiàn)了所有 ES6 中的類的功能以外,還添加了一些新的用法。
這一節(jié)主要介紹類的用法,讓我們平滑的從ES6過渡到Ts吧~
系列文章,收藏不走丟哦
一、什么是類
雖然 JavaScript 中有類的概念,但是可能大多數(shù) JavaScript 程序員并不是非常熟悉類,畢竟大部分人使用它的頻率并不高,所以我們來學(xué)一學(xué)類的基本使用。
- 類(Class):定義了一件事物的抽象特點(diǎn),包含它的屬性和方法
- 對象(Object):類的實(shí)例,通過 new 生成
1.1 屬性和方法
使用 class 定義類,使用constructor定義構(gòu)造函數(shù)。
通過 new 生成新實(shí)例的時候,會自動調(diào)用構(gòu)造函數(shù)。
class Male {constructor(name) {this.name = name;}getName() {return `My name is ${this.name}`;} }let man = new Male("余光"); console.log("man:", man.getName()); // My name is 余光1.2 類的繼承
使用extends關(guān)鍵字實(shí)現(xiàn)繼承,子類中使用super關(guān)鍵字來調(diào)用父類的構(gòu)造函數(shù)和方法。
class Animal {constructor(name) {this.name = name;}sayHi() {console.log("hi");} }class Cat extends Animal {constructor(name) {super(name); // 調(diào)用父類的constructor(name)console.log(">>>:", this.name);}sayHi() {return super.sayHi(); // 調(diào)用父類的 sayHi()} }const cat = new Cat("余光"); // 余光 cat.sayHi(); // hi1.3 存取器
使用 getter 和 setter 可以改變屬性的賦值和讀取行為:
class Animal {constructor(name) {this.name = name;}get name() {return "Jack";}set name(value) {console.log("setter: " + value);} }let a = new Animal("Kitty"); // setter: Kitty a.name = "Tom"; // setter: Tom console.log(a.name); // Jack1.4 實(shí)例屬性
1.1 小節(jié)里,想要初始化就需要在 constructor 內(nèi)進(jìn)行定義,在 ES7 中可以直接在類里面定義:
class Animal {name = "Jack";constructor() {// ...} }let a = new Animal(); console.log(a.name); // Jack1.5 靜態(tài)屬性
同樣在ES7 提案中,可以使用static定義一個靜態(tài)屬性:
class Animal {static num = 42;constructor() {// ...} }console.log(Animal.num); // 42二、TypeScript 中的類
2.1 基本使用
下面看一個使用類的例子:
class Notice {msg: string;constructor(message: string) {this.msg = message;}show() {return this.msg;} }const notice = new Notice("hi"); console.log(notice.show()); // hi你會發(fā)現(xiàn)我指定了 msg 的類型,并進(jìn)行賦值操作了。
2.2 繼承
在 TypeScript 里,我們可以使用常用的面向?qū)ο竽J健?基于類的程序設(shè)計(jì)中一種最基本的模式是允許使用繼承來擴(kuò)展現(xiàn)有的類。
看下面的例子:
class Animal {type: string;constructor(_type: string) {this.type = _type;}intro() {console.log(`I am a ${this.type}`);} }class Dog extends Animal {constructor(type: string) {super(type);}sayHi() {console.log("wang! wang!");} }const dog = new Dog("dog"); dog.intro(); // I am a dog dog.sayHi(); // wang wang通過 extends 關(guān)鍵字。Dog繼承了Animal的方法和屬性
因?yàn)?Dog 繼承了 Animal 的功能,因此我們可以創(chuàng)建一個 Dog 的實(shí)例,它能夠intro()和sayHi()。
2.3 修飾符
TypeScript可以使用幾種訪問修飾符分別是:
- public 修飾的屬性或方法是公有的,可以在任何地方被訪問到,默認(rèn)所有的屬性和方法都是 public 的
- private 修飾的屬性或方法是私有的,不能在聲明它的類的外部訪問
- protected 修飾的屬性或方法是受保護(hù)的,它和 private 類似,區(qū)別是它在子類中也是允許被訪問的
- readonly 屬性設(shè)置為只讀的,只讀屬性必須在聲明時或構(gòu)造函數(shù)里被初始化。
理解public
在上面的例子里,我們可以自由的訪問程序里定義的成員。就會注意到我們在之前的代碼里并沒有使用 public 來做修飾;
你也可以明確的將一個成員標(biāo)記成 public。我們可以用下面的方式來重寫上面的 Animal 類:
class Animal {public type: string;public constructor(_type: string) {this.type = _type;}public intro() {console.log(`I am a ${this.type}`);} }理解private
當(dāng)成員被標(biāo)記成private時,它就不能在聲明它的類的外部訪問。比如:
class Animal {private name: string;constructor(_name: string) {this.name = _name;}sayHi(){console.log(this.name)} }const dog = new Animal('dog'); dog.name; // error: 屬性“name”為私有屬性,只能在類“Animal”中訪問理解 protected
protected 修飾符與 private 修飾符的行為很相似,但有一點(diǎn)不同,protected 成員在派生類中仍然可以訪問。例如:
class Animal {protected name: string;constructor(_name: string) {this.name = _name;}sayHi(){console.log(this.name)} }class Dog extends Animal {name: stringconstructor(name: string){super(name)} }const dog = new Dog('dog'); console.log('>>>', dog.name); // dog注意,我們不能在Animal類外使用name,但是我們?nèi)匀豢梢酝ㄟ^Dog類的實(shí)例方法訪問,因?yàn)镈og是由Animal派生而來的。
理解readonly
你可以使用readonly關(guān)鍵字將屬性設(shè)置為只讀的。 只讀屬性必須在聲明時或構(gòu)造函數(shù)里被初始化。
class Animal {readonly name: string;constructor(_name: string) {this.name = _name;} } let dad = new Animal("dog"); dad.name = "apples"; // error 無法分配到 "name" ,因?yàn)樗侵蛔x屬性2.4 存取器
和ES6中的一樣,TypeScript同樣支持通過getters/setters來截取對對象成員的訪問。
還是那個Animal類,我們循序漸進(jìn)的添加get和set。
class Animal {name: string; }let dog = new Animal(); dog.name = "柯基"; if (dog.name) {console.log(dog.name); }上面的例子我們要加一個set和get:
class Animal {private _name: string;get name() {return this._name;}set name(newName: string) {if (newName === "柯基") {this._name = newName;} else {this._name = "新用戶";}} }let dog = new Animal(); dog.name = "小柯基"; console.log(dog.name); // 新用戶2.5 靜態(tài)屬性
到目前為止,我們只討論了類的實(shí)例成員,那些僅當(dāng)類被實(shí)例化的時候才會被初始化的屬性,我們也可以創(chuàng)建類的靜態(tài)成員,同樣和ES6一樣,我們來看一下:
class Dog {static staticName = "dog";getName(){console.log(Dog.staticName)} } Dog.staticName; // dog new Dog().getName(); // dog2.6 抽象類
抽象類做為其它派生類的基類使用。它們一般不會直接被實(shí)例化。不同于接口,抽象類可以包含成員的實(shí)現(xiàn)細(xì)節(jié)。
abstract關(guān)鍵字是用于定義抽象類和在抽象類內(nèi)部定義抽象方法。
abstract class Animal {abstract makeSound(): void;sayHi(): void {console.log("Hi.");} }// error class Dog extends Animal {// error 非抽象類“Dog”不會實(shí)現(xiàn)繼承自“Animal”類的抽象成員“makeSound”// 必須要對抽象類中的抽象方法進(jìn)行實(shí)現(xiàn),屬性也是一樣 }// good class Cat extends Animal {makeSound() :void{console.log('miao miao~');} } const cat = new Cat(); cat.sayHi(); // hi cat.makeSound(); // miao miao~抽象類中的抽象方法不包含具體實(shí)現(xiàn)并且必須在派生類中實(shí)現(xiàn)。抽象方法的語法與接口方法相似。兩者都是定義方法簽名但不包含方法體。 然而,抽象方法必須包含abstract關(guān)鍵字并且可以包含訪問修飾符。
2.7 把類當(dāng)做接口使用
類定義會創(chuàng)建兩個東西:
因?yàn)轭惪梢詣?chuàng)建出類型,所以你能夠在允許使用接口的地方使用類。
class Point {x: number;y: number; }interface Point3d extends Point {z: number; }let point3d: Point3d = { x: 1, y: 2, z: 3 };寫在最后
本篇文章是《Typescript入門首次》的第四篇文章,本篇文章主要聊一聊Ts中的類是什么樣子的,旨在讓我們在類這部分從ES6過渡到ts能更平滑一些,歡迎小伙伴們積極踴躍的互動,我會及時回復(fù)的哦,下一篇我們聊一聊由類衍生出來的專題《類與接口》
如果對你有幫助的話不妨收藏一下吧
系列文章傳送門:
關(guān)于我
- 花名:余光
- WX:j565017805
- 郵箱:webbj97@163.com
其他沉淀
- Js版LeetCode題解
- 前端進(jìn)階筆記
- CSDN 博客匯總
總結(jié)
以上是生活随笔為你收集整理的【TypeScript 专题】之 Ts 中的类(class)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SAP ABAP 培训测试 试卷 答案
- 下一篇: HttpClient下载图片实例