▓▓▓▓▓▓ 大致介紹 在ECMASript6中引入了類這一概念,通過class聲明一個類。對於學習過C和C++的人應該不會陌生 ▓▓▓▓▓▓ 類 看一個簡單的類: 在上面的例子中,利用class關鍵字聲明瞭一個類Greeter,在類中,定義了一個屬性,一個構造函數和一個方法 ▓▓▓▓▓▓ 繼承 類 ...
▓▓▓▓▓▓ 大致介紹
在ECMASript6中引入了類這一概念,通過class聲明一個類。對於學習過C和C++的人應該不會陌生
▓▓▓▓▓▓ 類
看一個簡單的類:
class Greeter { greeting: string; constructor(message: string){ this.greeting = message; }; greet(){ return "Hello, " + this.greeting; } } let greeter = new Greeter('world');
在上面的例子中,利用class關鍵字聲明瞭一個類Greeter,在類中,定義了一個屬性,一個構造函數和一個方法
▓▓▓▓▓▓ 繼承
類通常都是用來繼承的,但是Typescript中的繼承和C中的繼承還是有點差別的
例如:
class Animal { name:string; constructor(theName: string) { this.name = theName; } move(distanceInMeters: number = 0) { console.log(`${this.name} moved ${distanceInMeters}m.`); } } class Snake extends Animal { constructor(name: string) { super(name); } move(distanceInMeters = 5) { console.log("Slithering..."); super.move(distanceInMeters); } } class Horse extends Animal { constructor(name: string) { super(name); } move(distanceInMeters = 45) { console.log("Galloping..."); super.move(distanceInMeters); } } let sam = new Snake("Sammy the Python"); let tom: Animal = new Horse("Tommy the Palomino"); sam.move(); tom.move(34);
首先定義了一個類Animal,之後利用關鍵字extends定義了一個繼承Animal的類Snake,可以發現在Snake的構造函數里使用了super()方法,這是因為包含constructor函數的派生類必須調用super(),它會執行基類的構造方法。
在繼承類中重寫了構造函數,super.move()是繼承父類的方法
▓▓▓▓▓▓ public、private和protected
這三個概念對於學習過C的人應該很容易理解
public:公開的,在類外也是可以訪問的
之前寫的類中都是預設為public
class Animal { public name: string; public constructor(theName: string) { this.name = theName; } public move(distanceInMeters: number) { console.log(`${this.name} moved ${distanceInMeters}m.`); } }
private:私有的,只有在該類中可以訪問,在繼承類中都不可訪問
class Animal { private name: string; public constructor(message: string){ this.name = message; } } let animal = new Animal('cat'); animal.name;//error
protected:保護的,是介於public和private之間的,和private的區別就是在繼承類中時可以訪問的
class Animal { private name: string; protected sex: string; public constructor(message: string){ this.name = message; } } class Snake extends Animal { constructor(message){super(message)}; get(){ console.log(this.name); //error console.log(this.sex); } }
在上面的例子中,name是private,在繼承類中是不可以訪問的,而sex是可以被訪問的,當然這兩個屬性在類外都不可以被訪問
註意:如果一個類的構造函數被聲明為protected,這意味著這個類不能在包含它的類外被實例化,但是能被繼承。
▓▓▓▓▓▓ readonly修飾符
可以用關鍵字readonly聲明屬性為只讀的,只讀屬性必須是在聲明時或者構造函數里初始化
class Octopus { readonly name: string; readonly numberOfLegs: number = 8; constructor (theName: string) { this.name = theName; } } let dad = new Octopus("Man with the 8 strong legs"); dad.name = "Man with the 3-piece suit"; // error! name is readonly.
▓▓▓▓▓▓ 參數屬性
利用參數屬性可以簡寫很多代碼
class Octopus { name: string; constructor (theName: string) { this.name = theName; } } //利用參數屬性 class Octopus { constructor(public name: string){} }
這兩段代碼的作用是一樣的
▓▓▓▓▓▓ 存取器
TypeScript支持getters/setters來截取對對象成員的訪問。 它能幫助你有效的控制對對象成員的訪問。
let passcode = "secret passcode"; class Employee { private _fullName: string; get fullName(): string { return this._fullName; } set fullName(newName: string) { if (passcode && passcode == "secret passcode") { this._fullName = newName; } else { console.log("Error: Unauthorized update of employee!"); } } } let employee = new Employee(); employee.fullName = "Bob Smith"; if (employee.fullName) { alert(employee.fullName); }
▓▓▓▓▓▓ 抽象類
抽象類是供其它類繼承的基類。 他們一般不會直接被實例化。 不同於介面,抽象類可以包含成員的實現細節。abstract關鍵字是用於定義抽象類和在抽象類內部定義抽象方法。抽象類中的抽象方法不包含具體實現並且必須在派生類中實現。
abstract class Department { constructor(public name: string) { } printName(): void { console.log('Department name: ' + this.name); } abstract printMeeting(): void; // 必須在派生類中實現 } class AccountingDepartment extends Department { constructor() { super('Accounting and Auditing'); // constructors in derived classes must call super() } printMeeting(): void { console.log('The Accounting Department meets each Monday at 10am.'); } generateReports(): void { console.log('Generating accounting reports...'); } } let department: Department; // ok to create a reference to an abstract type department = new Department(); // error: cannot create an instance of an abstract class department = new AccountingDepartment(); // ok to create and assign a non-abstract subclass department.printName(); department.printMeeting(); department.generateReports(); // error: method doesn't exist on declared abstract type
參考資料: