使用class申明
一、继承
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 { // 使用extends关键字继承constructor(name: string) { super(name); } // 在使用this之前,必须现使用supermove(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);
二、公共,私有与受保护的修饰符
都过没有使用关键字,默认都是“public”
class Person {protected name: string; // protected表示受保护的,只可在本身和派生类中使用constructor(name: string) { this.name = name; }}class Employee extends Person {private department: string; // private表示私有,只在该类申明中可以使用constructor(name: string, department: string) {super(name)this.department = department;}public getElevatorPitch() { // public表示公共类,默认return `Hello, my name is ${this.name} and I work in ${this.department}.`;}}let howard = new Employee("Howard", "Sales");console.log(howard.getElevatorPitch());console.log(howard.name); // 错误
三、readonly 修饰符
只读属性必须在声明时或构造函数里被初始化。
class Octopus {readonly name: string;readonly numberOfLegs: number = 8;constructor (theName: string) {this.name = theName;}// constructor(private name: string) { } // 也可以使用参数属性来申明,参数属性通过给构造函数参数添加一个访问限定符来声明,比如private、public或protected}let dad = new Octopus("Man with the 8 strong legs");dad.name = "Man with the 3-piece suit"; // 错误! name 是只读的.
四、存取器
截取对对象成员的访问,一个拦截器
const fullNameMaxLength = 10;class Employee {private _fullName: string;get fullName(): string { // getters,读取值的时候,会触发这个方法return this._fullName;}set fullName(newName: string) { // setters,设置某个值的时候,会触发这个方法if (newName && newName.length > fullNameMaxLength) {throw new Error("fullName has a max length of " + fullNameMaxLength);}this._fullName = newName;}}let employee = new Employee();employee.fullName = "Bob Smith"; // 设置if (employee.fullName) {alert(employee.fullName);}
五、静态属性
存在于类本身上面而不是类的实例上,不需要实例话就可以访问的属性,使用static关键字
class Grid {static origin = {x: 0, y: 0}; // 定义静态属性calculateDistanceFromOrigin(point: {x: number; y: number;}) {let xDist = (point.x - Grid.origin.x); // 读取静态属性let yDist = (point.y - Grid.origin.y);return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale;}constructor (public scale: number) { }}let grid1 = new Grid(1.0); // 1x scalelet grid2 = new Grid(5.0); // 5x scaleconsole.log(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));console.log(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));
六、抽象类
抽象类做为其它派生类的基类使用,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'); // 在派生类的构造函数中必须调用 super()}printMeeting(): void {console.log('The Accounting Department meets each Monday at 10am.');}generateReports(): void {console.log('Generating accounting reports...');}}let department: Department; // 允许创建一个对抽象类型的引用department = new Department(); // 错误: 不能创建一个抽象类的实例department = new AccountingDepartment(); // 允许对一个抽象子类进行实例化和赋值department.printName();department.printMeeting();department.generateReports(); // 错误: 方法在声明的抽象类中不存在
七、高级技巧
1,构造函数
class Greeter {static standardGreeting = "Hello, there"; // 申明静态属性greeting: string; // 申明公共属性greet() {if (this.greeting) {return "Hello, " + this.greeting;}else {return Greeter.standardGreeting;}}}let greeter1: Greeter; // 把类当类型使用greeter1 = new Greeter();console.log(greeter1.greet());let greeterMaker: typeof Greeter = Greeter; // 申明的这个变量类型是Greeter,值也是GreetergreeterMaker.standardGreeting = "Hey there!"; // 可以读取这个类的静态方法let greeter2: Greeter = new greeterMaker();// 可以实例话刚才申明的类console.log(greeter2.greet());
2,把类当做接口使用
class Point {x: number;y: number;}interface Point3d extends Point {z: number;}let point3d: Point3d = {x: 1, y: 2, z: 3};
