在ECMASript6中引入了類這一律念,經過class聲明一個類。對於學習過C和C++的人應該不會陌生git
看一個簡單的類:typescript
class Greeter { greeting: string; constructor(message: string){ this.greeting = message; }; greet(){ return "Hello, " + this.greeting; } } let greeter = new Greeter('world');
在上面的例子中,利用class關鍵字聲明瞭一個類Greeter,在類中,定義了一個屬性,一個構造函數和一個方法函數
類一般都是用來繼承的,可是Typescript中的繼承和C中的繼承仍是有點差異的學習
例如:ui
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(),它會執行基類的構造方法。this
在繼承類中重寫了構造函數,super.move()是繼承父類的方法spa
這三個概念對於學習過C的人應該很容易理解code
public:公開的,在類外也是能夠訪問的對象
以前寫的類中都是默認爲publicblog
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聲明屬性爲只讀的,只讀屬性必須是在聲明時或者構造函數裏初始化
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
參考資料: