傳統(tǒng)的 JavaScript 程序使用函數(shù)和基于原型的繼承來(lái)創(chuàng)建可重用的組件,從 ES6 開(kāi)始庸推,JavaScript 程序能夠使用基于類的面向?qū)ο蟮姆绞叫粘唷J褂?TypeScript另萤,你可以使用 ES6 中規(guī)定的新特性浑槽,編譯后的 JavaScript 可以在所有主流瀏覽器和平臺(tái)上運(yùn)行。
基本用法
class Person {
public love: string;
constructor(love: string) {
this.love = love;
}
public sayLove() {
console.log(`my love is ${this.love}`)
}
}
繼承
在構(gòu)造器里訪問(wèn) this 的屬性之前领舰,一定要調(diào)用 super() 夫嗓,這個(gè)是 TypeScript 強(qiáng)制執(zhí)行的一條重要規(guī)則。
class Person {
public love: string;
constructor(love: string) {
this.love = love;
}
public sayLove() {
console.log(`my love is ${this.love}`)
}
}
class SuperPerson extends Person {
public name: string;
constructor(love: string, name: string) {
super(love);
this.name = name;
}
public sayName(){
console.log(`my name is ${this.name}`)
}
}
let me = new SuperPerson('HTML', 'funlee');
me.sayLove()
me.sayName()
訪問(wèn)控制
public冲秽、private舍咖、protected
默認(rèn)是 public, 不再贅述锉桑,參考前面例子排霉。
當(dāng)成員標(biāo)記為 private 時(shí),它就不能在聲明它的類的外部訪問(wèn)民轴,用 protected 修飾的屬性依然如此攻柠。
class Person {
private love: string; // or prot
constructor(love: string) {
this.love = love;
}
public sayLove() {
console.log(`my love is ${this.love}`)
}
}
let me = new Person('TS');
me.love = 'JS'; // error
private 和 protected 有一點(diǎn)不同, protected 成員在派生類中仍然可以訪問(wèn)后裸。例如:
class Person {
protected name: string;
constructor(name: string) {
this.name = name;
}
}
class Man extends Person {
private love: string;
constructor(name: string, love: string) {
super(name);
this.love = love;
}
public say() {
// 如果Person 中用 private 修飾 name 則不能訪問(wèn)到 name 屬性
console.log(`my name is ${this.name}, and my love is ${this.love}`);
}
}
let me = new Man('funlee', 'TS');
注意:TypeScript 使用的是結(jié)構(gòu)性類型系統(tǒng)瑰钮,所以當(dāng)比較兩種不同的類型時(shí),如果所有的成員的類型都是兼容的微驶,那么這兩個(gè)類型就是兼容的浪谴。如:
class A {
prop1: string
}
class B {
prop1: string
prop2: string
}
let instance:A = new B() // 允許這么做,因?yàn)锳的所有成員類型因苹,B中都有
但是如果被比較的類里面含有 private 和 protected 類型成員的時(shí)候苟耻,情況就不同了,這時(shí)候需要另一個(gè)類里也含有相應(yīng)的 private 或 protected 成員扶檐,類型才能是兼容的凶杖,所以有:
class A {
private prop1: string
}
class B {
private prop2: string
}
let p1:A = new B() // 報(bào)錯(cuò)
class C extends A {
}
let p2:A = new C() // 允許這么做
readonly
可以使用 readonly 關(guān)鍵字將屬性設(shè)置為只讀的,只讀屬性必須在聲明時(shí)或構(gòu)造函數(shù)里被初始化蘸秘。
class Person {
readonly name: string;
constructor(name: string) {
this.name = name;
}
}
let me = new Person('funlee');
me.name = 'new name'; // error
參數(shù)屬性
參數(shù)屬性允許同時(shí)創(chuàng)建和初始化成員官卡,可以把聲明和賦值合并至一處蝗茁,如:
class Person {
constructor(public name: string, protected love: string, readonly age: number, private weight: string) {
this.name = name;
this.love = love;
this.age = age;
}
public sayWeight() {
console.log(`my weight is ${this.weight}`)
}
}
let me = new Person('funlee', 'TS', 18, '55kg');
me.sayWeight()
存取器
TypeScript 支持 getter 和 setter醋虏,但是有一點(diǎn)限制:編譯器輸出必須設(shè)為 ES5 或者更高寻咒,不支持降級(jí)到 ES3,另外颈嚼,當(dāng)一個(gè)存取器只帶有 get 卻不帶有 set 時(shí)毛秘,它會(huì)被自動(dòng)推斷為 readonly。
class Person {
public _love: string;
constructor(love: string) {
this._love = love;
}
get love(): string{
return this._love;
}
set love(newLove: string) {
this._love = `error!! my love can't be chenged`;
}
}
let me = new Person('TS');
console.log(me.love); // TS
me.love = 'HTML';
console.log(me.love); // error!! my love can't be chenged
靜態(tài)屬性
可以使用static來(lái)定義類里的靜態(tài)屬性阻课,靜態(tài)屬性屬于類自身叫挟,而不屬于實(shí)例,訪問(wèn)的時(shí)候要用類名訪問(wèn)限煞,而不能用實(shí)例對(duì)象訪問(wèn)抹恳,如:
class Person {
static love: string = 'TS';
}
let me = new Person();
console.log(Person.love); // TS
console.log(me.love); // error
抽象類
抽象類只能作為其他派生類的基類使用,抽象類不能被實(shí)例化署驻,它具有如下特點(diǎn):
- 抽象類可以包含成員的實(shí)現(xiàn)細(xì)節(jié)奋献,且抽象類必須用 abstract 聲明
- 抽象類里不含方法體的方法稱為抽象方法,使用 abstract 聲明旺上,抽象方法必須被子類實(shí)現(xiàn)(抽象方法必須使用 abstract 關(guān)鍵字聲明瓶蚂,且可以包含訪問(wèn)修飾符)
abstract class Person {
public love: string;
constructor(love: string) {
this.love = love;
}
abstract sayLove(): string; // 必須在派生類中實(shí)現(xiàn)
}
class Man extends Person{
constructor(love: string){
super(love)
}
sayLove() {
return `my love is ${this.love}`;
}
}
let me = new Man('TS');
console.log(me.sayLove()); // my love is TS
把類當(dāng)做接口使用
類定義會(huì)創(chuàng)建兩個(gè)東西:類的實(shí)例類型和一個(gè)構(gòu)造函數(shù),因?yàn)轭惪梢詣?chuàng)建出類型宣吱,所以能夠在允許使用接口的地方使用類窃这。
class Person {
name: string;
age: number;
}
interface Man extends Person {
love: string;
}
let me: Man = {
name: 'funlee',
age: 18,
love: 'TS'
}