使用class申明

一、继承

  1. class Animal { // 基类
  2. name: string;
  3. constructor(theName: string) { this.name = theName; }
  4. move(distanceInMeters: number = 0) {
  5. console.log(`${this.name} moved ${distanceInMeters}m.`);
  6. }
  7. }
  8. class Snake extends Animal { // 使用extends关键字继承
  9. constructor(name: string) { super(name); } // 在使用this之前,必须现使用super
  10. move(distanceInMeters = 5) {
  11. console.log("Slithering...");
  12. super.move(distanceInMeters);
  13. }
  14. }
  15. class Horse extends Animal {
  16. constructor(name: string) { super(name); }
  17. move(distanceInMeters = 45) {
  18. console.log("Galloping...");
  19. super.move(distanceInMeters);
  20. }
  21. }
  22. let sam = new Snake("Sammy the Python");
  23. let tom: Animal = new Horse("Tommy the Palomino");
  24. sam.move();
  25. tom.move(34);

二、公共,私有与受保护的修饰符

都过没有使用关键字,默认都是“public”

  1. class Person {
  2. protected name: string; // protected表示受保护的,只可在本身和派生类中使用
  3. constructor(name: string) { this.name = name; }
  4. }
  5. class Employee extends Person {
  6. private department: string; // private表示私有,只在该类申明中可以使用
  7. constructor(name: string, department: string) {
  8. super(name)
  9. this.department = department;
  10. }
  11. public getElevatorPitch() { // public表示公共类,默认
  12. return `Hello, my name is ${this.name} and I work in ${this.department}.`;
  13. }
  14. }
  15. let howard = new Employee("Howard", "Sales");
  16. console.log(howard.getElevatorPitch());
  17. console.log(howard.name); // 错误

三、readonly 修饰符

只读属性必须在声明时或构造函数里被初始化。

  1. class Octopus {
  2. readonly name: string;
  3. readonly numberOfLegs: number = 8;
  4. constructor (theName: string) {
  5. this.name = theName;
  6. }
  7. // constructor(private name: string) { } // 也可以使用参数属性来申明,参数属性通过给构造函数参数添加一个访问限定符来声明,比如private、public或protected
  8. }
  9. let dad = new Octopus("Man with the 8 strong legs");
  10. dad.name = "Man with the 3-piece suit"; // 错误! name 是只读的.

四、存取器

截取对对象成员的访问,一个拦截器

  1. const fullNameMaxLength = 10;
  2. class Employee {
  3. private _fullName: string;
  4. get fullName(): string { // getters,读取值的时候,会触发这个方法
  5. return this._fullName;
  6. }
  7. set fullName(newName: string) { // setters,设置某个值的时候,会触发这个方法
  8. if (newName && newName.length > fullNameMaxLength) {
  9. throw new Error("fullName has a max length of " + fullNameMaxLength);
  10. }
  11. this._fullName = newName;
  12. }
  13. }
  14. let employee = new Employee();
  15. employee.fullName = "Bob Smith"; // 设置
  16. if (employee.fullName) {
  17. alert(employee.fullName);
  18. }

五、静态属性

存在于类本身上面而不是类的实例上,不需要实例话就可以访问的属性,使用static关键字

  1. class Grid {
  2. static origin = {x: 0, y: 0}; // 定义静态属性
  3. calculateDistanceFromOrigin(point: {x: number; y: number;}) {
  4. let xDist = (point.x - Grid.origin.x); // 读取静态属性
  5. let yDist = (point.y - Grid.origin.y);
  6. return Math.sqrt(xDist * xDist + yDist * yDist) / this.scale;
  7. }
  8. constructor (public scale: number) { }
  9. }
  10. let grid1 = new Grid(1.0); // 1x scale
  11. let grid2 = new Grid(5.0); // 5x scale
  12. console.log(grid1.calculateDistanceFromOrigin({x: 10, y: 10}));
  13. console.log(grid2.calculateDistanceFromOrigin({x: 10, y: 10}));

六、抽象类

抽象类做为其它派生类的基类使用,abstract 关键字是用于定义抽象类和在抽象类内部定义抽象方法。类似于类的接口

  1. abstract class Department {
  2. constructor(public name: string) {
  3. }
  4. printName(): void {
  5. console.log('Department name: ' + this.name);
  6. }
  7. abstract printMeeting(): void; // 必须在派生类中实现
  8. }
  9. class AccountingDepartment extends Department {
  10. constructor() {
  11. super('Accounting and Auditing'); // 在派生类的构造函数中必须调用 super()
  12. }
  13. printMeeting(): void {
  14. console.log('The Accounting Department meets each Monday at 10am.');
  15. }
  16. generateReports(): void {
  17. console.log('Generating accounting reports...');
  18. }
  19. }
  20. let department: Department; // 允许创建一个对抽象类型的引用
  21. department = new Department(); // 错误: 不能创建一个抽象类的实例
  22. department = new AccountingDepartment(); // 允许对一个抽象子类进行实例化和赋值
  23. department.printName();
  24. department.printMeeting();
  25. department.generateReports(); // 错误: 方法在声明的抽象类中不存在

七、高级技巧

类定义会创建两个东西:类的实例类型和一个构造函数

1,构造函数

  1. class Greeter {
  2. static standardGreeting = "Hello, there"; // 申明静态属性
  3. greeting: string; // 申明公共属性
  4. greet() {
  5. if (this.greeting) {
  6. return "Hello, " + this.greeting;
  7. }
  8. else {
  9. return Greeter.standardGreeting;
  10. }
  11. }
  12. }
  13. let greeter1: Greeter; // 把类当类型使用
  14. greeter1 = new Greeter();
  15. console.log(greeter1.greet());
  16. let greeterMaker: typeof Greeter = Greeter; // 申明的这个变量类型是Greeter,值也是Greeter
  17. greeterMaker.standardGreeting = "Hey there!"; // 可以读取这个类的静态方法
  18. let greeter2: Greeter = new greeterMaker();// 可以实例话刚才申明的类
  19. console.log(greeter2.greet());

2,把类当做接口使用

  1. class Point {
  2. x: number;
  3. y: number;
  4. }
  5. interface Point3d extends Point {
  6. z: number;
  7. }
  8. let point3d: Point3d = {x: 1, y: 2, z: 3};