▓▓▓▓▓▓ 大致介绍
在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
参考资料: