類接口 · TypeScript 入門教程 (xcatliu.com)
十四.類
① 類
- 類:定義了一件事物的抽象特點,包含它的屬性和方法
- 對象:類的實例,通過new生成
- 面向對象(OOP)的三大特性:封裝、繼承、多態(tài)
- 封裝(Encapsulation):將對數據的操作細節(jié)隱藏起來,只暴露對外的接口。外界調用端不需要(也不可能)知道細節(jié),就能通過對外提供的接口來訪問該對象,同時也保證了外界無法任意更改對象內部的數據
- 繼承(Inheritance):子類繼承父類,子類除了擁有父類的所有特性外,還有一些更具體的特性
- 多態(tài)(Polymorphism):由繼承而產生了相關的不同的類,對同一個方法可以有不同的響應。比如?
Cat
?和?Dog
?都繼承自?Animal
,但是分別實現了自己的?eat
?方法。此時針對某一個實例,我們無需了解它是?Cat
?還是?Dog
,就可以直接調用?eat
?方法,程序會自動判斷出來應該如何執(zhí)行?eat
- 存取器(getter & setter):用以改變屬性的讀取和賦值行為
- 修飾符(Modifiers):修飾符是一些關鍵字,用于限定成員或類型的性質。比如?
public
?表示公有屬性或方法 - 抽象類(Abstract Class):抽象類是供其他類繼承的基類,抽象類不允許被實例化。抽象類中的抽象方法必須在子類中被實現
- 接口(Interfaces):不同類之間公有的屬性或方法,可以抽象成一個接口。接口可以被類實現(implements)。一個類只能繼承自另一個類,但是可以實現多個接口
TypeScript中類的用法
- public:修飾的屬性或方法是公有的,可以在任何地方被訪問到,默認所有的屬性和方法都是?
public
?的 - private:修飾的屬性或方法是私有的,不能在聲明它的類的外部訪問
- protected??修飾的屬性或方法是受保護的,它和?
private
?類似,區(qū)別是它在子類中也是允許被訪問的
class Animal {
public name;
public constructor(name) {
this.name = name;
}
}
let a = new Animal('Jack');
console.log(a.name); // Jack
a.name = 'Tom';
console.log(a.name); // Tom
-
使用private修飾的屬性或者方法,在子類中也是不允許訪問的
-
protected 修飾的,允許在子類中訪問
class Animal {
protected name
public constructor(name: string) {
this.name = name
}
}
class Cat extends Animal {
constructor(name: string) {
super(name)
console.log(this.name)
}
}
-
構造函數修飾為 private 時,該類不允許被繼承或者實例化
-
當構造函數修飾為??protected 時,該類只允許被繼承
參數屬性
- 修飾符和readonly還可以使用在構造函數參數中,等同于類中定義該屬性同時給該屬性賦值,使代碼更簡潔
class Animal {
// public name: string;
public constructor(public name) {
// this.name = name;
}
}
-
readonly : 只讀屬性關鍵字,只允許出現在屬性聲明或索引簽名或構造函數中
- ? 如果?readonly 和其他訪問修飾符同時存在的話,需要寫在其后面
class Animal {
// public readonly name;
public constructor(public readonly name) {
// this.name = name;
}
}
抽象類
abstract 用于定義抽象類和其中的抽象方法
(1)抽象類是不允許被實例化的
(2) 抽象類中的抽象方法必須被子類實現
abstract class Animal {
public name
public constructor(name: string) {
this.name = name
}
public abstract sayHi(): any
}
class Cat extends Animal {
public eat() {
console.log(`${this.name} is eating.`)
}
public sayHi(): any {
console.log(`Meow, My name is ${this.name}`)
}
}
let cat = new Cat('Tom')
十五.類與接口
① 接口可以對類的一部分行為進行描述
② 類實現接口
- 不同的類之間可以有一些共有的特性,就可以將這些特性提取為接口
- 使用 implements 關鍵字來實現
- 提高面對對象的靈活性
- ?舉例
門是一個類,防盜門是門的子類,如果防盜門有一個報警器的功能,可以給防盜門添加一個報警方法,如果有另一個類:車,也有報警器的功能,就可以考慮把報警器提取出來,作為一個接口,防盜門和門都去實現它
interface Alarm {
alert(): void
}
class Door {}
class SecurityDoor extends Door implements Alarm {
alert() {
console.log('SecurityDoor alert')
}
}
class Car implements Alarm {
alert() {
console.log('Car alert')
}
}
- 一個類可以實現多個接口
③ 接口繼承接口
- 接口與接口之間可以是繼承關系
- 除了擁有alert方法以外,還擁有兩個新方法?
lightOn
?和?lightOff
interface Alarm {
alert(): void
}
interface LightableAlarm extends Alarm {
lightOn(): void
lightOff(): void
}
④ 接口繼承類
-
接口繼承類的時候,只會繼承它的實例屬性和實例方法
十六.泛型
① 泛型的概念
- 泛型:定義函數,接口或類的時候,不預先指定具體的類型,而是在指定的時候再指定類型的一種特性
- 在函數名后面添加了<T>, 其中T用來指代任意輸入的類型,在后面的輸入value:T 和輸出 Array<T> 中就可以使用了
function createArray<T>(length: number, value: T): Array<T> {
let result: T[] = []
for (let i = 0; i < length; i++) {
result[i] = value
}
return result
}
console.log(createArray<string>(3, 'x'))
- 可以定義多個類型參數
function swap<T, U>(tuple: [T, U]): [U, T] {
return [tuple[1], tuple[0]]
}
console.log(swap([7, 'seven']))
② 泛型的約束
- 在函數內部使用泛型變量的時候,由于事先不知道它是哪種類型,所以不能隨意的操作它的屬性或者方法
? ??
-
可以對泛型進行約束,只允許這個函數傳入那些包含length屬性的變量,這就是泛型約束
-
多個類型參數之間可以互相約束
③ 泛型接口
interface CreateArrayFunc {
<T>(length: number, value: T): Array<T>
}
let createArr: CreateArrayFunc
createArr = function <T>(length: number, value: T): Array<T> {
let result: T[] = []
for (let i = 0; i < length; i++) {
result[i] = value
}
return result
}
console.log(createArr(3, 'x'))
-
可以把泛型接口提前到接口名上
④ 泛型類: 泛型可以用于類的類型定義中
class GenericNumber<T> {
zeroValue: T
add: (x: T, y: T) => T
}
let myGenericNumber = new GenericNumber<number>()
myGenericNumber.zeroValue = 0
myGenericNumber.add = function (x, y) {
return x + y
}
⑤ 泛型參數的默認類型
TypeScript 2.3 之后,就可以為泛型中的類型參數指定默認類型,當使用泛型時,沒有在代碼中直接指定類型參數,從實際值參數中也無法推測出時,這個默認類型就會起作用
十七.聲明合并
- 如果定義了兩個相同名字的函數,接口或類,他們會合并成一個類型
① 函數的合并(重載)
function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string {
if (typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === 'string') {
return x.split('').reverse().join('');
}
}
② 接口的合并
- 合并的屬性的類型必須是唯一的
③ 類的合并
類的合并與接口的合并規(guī)則一致
十八.編譯選項
① allowJs? 允許編譯js文件文章來源:http://www.zghlxwxcb.cn/news/detail-705317.html
- 一般在項目js, ts混合開發(fā)中需要設置
- 設置為true時,js文件會被tsc編譯,否則不會
- 設置為true的時候,編譯后的文件包含foo.js
- 設置為false的時候,編譯后的文件不包含foo.js
②?allowSyntheticDefaultImports??允許對不包含默認導出的模塊使用默認導入。這個選項不會影響生成的代碼,只會影響類型檢查文章來源地址http://www.zghlxwxcb.cn/news/detail-705317.html
- 在ts中,如果要引入一個export = foo 導出的模塊,標準語法是??import foo = require('foo')? ?或者?import * as foo from 'foo'
- 但是已經習慣使用?import foo from 'foo' ,所以使用了這個設置項
- 如果設置為true, 就允許使用?import foo from 'foo' 來導入一個通過??export = foo 導出的模塊,當它設置為false時,則不允許,會報錯
到了這里,關于typeScript 學習筆記(二)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!