目錄
- 1,抽象類
- 1,為什么需要抽象類
- 2,抽象成員
- 3,設計模式-模板模式
- 2,靜態成員
- 1,什么是靜態成員
- 2,設計模式-單例模式
1,抽象類
1,為什么需要抽象類
有時,某個類只表示一個抽象的概念,主要用于提取子類的公共成員,而不是直接創建它的實例對象。此時,這個類可以作為抽象類。
實現:在類名前加 abstract
,抽象類不可以通過 new 來創建實例對象。
2,抽象成員
有時,一些公共成員是必須存在的,但還不確定成員的值或具體實現。因為,需要一種強約束,讓繼承的子類必須實現這些成員。
也就是說,抽象類中定義的抽象成員,在子類中必須實現。
如果子類也是抽象類,則可以不實現父類中的抽象成員或方法。
子類的3種實現方式:
abstract class Chess {abstract readonly name: string;
}// 第1種
class Horse extends Chess {readonly name: string = "馬";
}// 第2種
class Pao extends Chess {readonly name: string;constructor() {super();this.name = "炮";}
}// 第3種
class Soldier extends Chess {get name() {return "兵";}
}
3,設計模式-模板模式
當某個公共方法中,一部分是公共邏輯,一部分又是私有邏輯(需要再子類中實現)。
此時,可以不將該方法定義為抽象方法,而是將那部分私有邏輯定義為抽象方法,并在當前方法中調用即可。
這樣的強約束,可以只關注子類需要實現的東西,其他的父類已經完成。
abstract class Chess {abstract readonly name: string;move(targetX: number, targetY: number): boolean {// 第1和第2步屬于公共邏輯// 1,邊界條件判斷// 2,目標位置是否有己方棋子// 第3步屬于私有邏輯:不同兵種的移動規則(需要在子類中實現)if (this.rule(targetX, targetY)) {console.log("移動成功");return true;} else {return false;}}protected abstract rule(targetX: number, targetY: number): boolean;
}class Horse extends Chess {protected rule(targetX: number, targetY: number): boolean {return true; // 簡單實現,做測試使用。}readonly name: string = "馬";
}const horse = new Horse();
horse.move(2, 3);
2,靜態成員
1,什么是靜態成員
指附著在類上的成員(相當于構造函數的屬性),通過static修飾。
每個實例成員的相同屬性,理論上是不一樣的,所以那些相同的屬性應該作為靜態成員,附著在類上。
構造函數或非靜態方法中的this指向實例對象,如果要訪問當前類,直接使用類名即可。
靜態方法中的this指向當前類。
class User {static users: User[] = [];constructor(public id: string, public pwd: string, public name: string, public age: number) {User.users.push(this);}static login(loginId: string, loginPwd: string): User | undefined {// 靜態方法中 this 指向當前類return this.users.find((user) => user.id === loginId && user.pwd === loginPwd);}sayHello() {console.log(`我是${this.name}`);}
}new User("u1", "pwd1", "用戶1", 18);
new User("u2", "pwd2", "用戶2", 188);console.log(User.users);const user = User.login("u1", "pwd1");
if (user) {user.sayHello();
}
2,設計模式-單例模式
某些類的實例對象,在系統中只允許存在一個,為了避免開發者隨意創建實例對象而產生預期之外的錯誤,可以使用單例模式進行強約束。
構造函數私有化或抽象類,都不允許 new 實例對象。
class User {private constructor() {}private static _user?: User;static createUser() {if (!this._user) {this._user = new User();}return this._user;}
}const u1 = User.createUser();
const u2 = User.createUser();
console.log(u1 === u2);
下面的方式也可以創建單例,但有一些缺陷。
- 實例對象一開始就創建了,不是在需要時才創建。
- 做不到在創建單例對象時,提前執行一些代碼。
class User {private constructor() {}static readonly singleUser = new User()
}const u1 = User.singleUser;
const u2 = User.singleUser;
console.log(u1 === u2);
以上。