基礎説明
先來看個例子:
class Person {
name: string;
constructor(name: string) {
this.name = name;
}
say() {
return "你好,我是" + this.name;
}
}
這樣,我們就定義了一個類,包含一個屬性用於保存名稱,一個構造器用於創建的時候設置名稱,方法say用於獲取名稱描述:
let person = new Person("小強");
console.log(person.say());
打印的結果就是:“你好,我是小強”。
公共,私有與受保護的修飾符
也就是定義屬性、方法等的訪問權限,下面來具體説明。
public
默認訪問權限就是public,你可以自由的訪問程序裏定義的成員,比如上面的例子和下面的代碼是等價的:
class Person {
public name: string;
public constructor(name: string) {
this.name = name;
}
public say() {
return "你好,我是" + this.name;
}
}
private
當成員被標記成 private時,它就不能在聲明它的類的外部訪問,比如我們對上面的例子進行改造:
class Person {
private name: string;
constructor(name: string) {
this.name = name;
}
say() {
return "你好,我是" + this.name;
}
}
var person = new Person('小明');
可以看見,name現在是私有屬性了,那麼下面代碼依舊是可以的:
person.say();
而下面的代碼就不行:
// Property 'name' is private and only accessible within class 'Person'.
person.name;
温馨提示:兩個類如果所有的成員的類型都是兼容的,我們就認為它們的類型是兼容的,可是,比較帶有private或protected成員類型的時候,不只是類型需要相同,並且還需要來自同一份聲明。
protected
和private類似,唯一不同的是,除了可以在聲明它的類的內部訪問,還可以在派生類中訪問:
class Person {
protected name: string;
constructor(name: string) {
this.name = name;
}
}
class ChinaPerson extends Person {
constructor(name: string) {
super(name);
}
say() {
return "你好,我是" + this.name + ",我來自中國";
}
}
let chinaPerson = new ChinaPerson("小茜");
那麼,下面代碼也是可行的:
chinaPerson.say();
readonly修飾符
也就是標記只讀,只讀的屬性只能聲明時或構造函數裏被初始化,例如:
class Person {
readonly name: string = "小灰灰";
}
let person = new Person();
那麼,讀取是可以的:
person.name;
而下面當我們嘗試修改就會出錯:
// Cannot assign to 'name' because it is a read-only property.
person.name = "大灰灰";
參數屬性
如果只讀屬性希望通過構造函數初始化,可以這樣:
class Person {
readonly name: string;
constructor(name: string) {
this.name = name;
}
}
而更簡單的寫法是:
class Person {
constructor(readonly name: string) {
this.name = name;
}
}
靜態屬性
也就是那些歸屬類而不是對象的屬性或方法,例如:
class Person {
static age: number;
}
直接使用類即可訪問:
Person.age = 10;
而對象則無法訪問:
// Property 'age' does not exist on type 'Person'.
// Did you mean to access the static member 'Person.age' instead?ts(2576)
new Person().age = 10;
存取器
比如我們現在有一個場景:
class Person {
name: string;
}
那麼,我們創建好對象後就可以很容易的設置和獲取屬性name值:
let person = new Person();
person.name = "阿肥";
console.log(person.name);
可是現在有一個問題,name值在設置的時候必須滿足一定規則。怎麼辦?我們就可以把上面的類改寫成使用 getter 和 setter 來實現:
class Person {
private _name: string;
get name(): string {
return this._name;
}
set name(name: string) {
if (name.length > 4) {
this._name = name;
}
}
}
名稱設置名稱的時候,長度必須大於4,不然會設置失敗。
繼承
比如狗是動物,那麼狗就可以繼承動物上面的一些內容:
class Animal {
eat() {
console.log("我會吃飯");
}
}
class Dog extends Animal {
bark() {
console.log("我會狗叫");
}
}
動物的實例上就有eat方法,而狗除了eat還可以bark。
抽象類
和接口類似,只不過可以包含成員的實現細節,abstract關鍵字是用於定義抽象類和在抽象類內部定義抽象方法:
abstract class Dog {
abstract bark(): void;
run(): void {
console.log("我在跑");
}
}