<返回目录     Powered by claud/xia兄

第4课: 类Class

基本类定义

class Greeter {
  greeting: string;

  constructor(message: string) {
    this.greeting = message;
  }

  greet() {
    return "Hello, " + this.greeting;
  }
}

let greeter = new Greeter("world");
console.log(greeter.greet());

继承

class Animal {
  name: string;

  constructor(name: string) {
    this.name = name;
  }

  move(distance: number = 0) {
    console.log(`${this.name} moved ${distance}m.`);
  }
}

class Dog extends Animal {
  bark() {
    console.log("Woof! Woof!");
  }
}

const dog = new Dog("Buddy");
dog.bark();
dog.move(10);

访问修饰符

TypeScript支持三种访问修饰符:

class Person {
  public name: string;
  private age: number;
  protected email: string;

  constructor(name: string, age: number, email: string) {
    this.name = name;
    this.age = age;
    this.email = email;
  }

  public getAge(): number {
    return this.age;
  }
}

class Employee extends Person {
  private department: string;

  constructor(name: string, age: number, email: string, dept: string) {
    super(name, age, email);
    this.department = dept;
  }

  public getEmail(): string {
    return this.email; // 可以访问protected属性
  }
}

let person = new Person("Alice", 25, "alice@example.com");
console.log(person.name); // 正确
console.log(person.age); // 错误:age是私有的

readonly修饰符

class Octopus {
  readonly name: string;
  readonly numberOfLegs: number = 8;

  constructor(name: string) {
    this.name = name;
  }
}

let dad = new Octopus("Man with the 8 strong legs");
dad.name = "Man with the 3-piece suit"; // 错误!name是只读的

参数属性

在构造函数参数中使用修饰符可以自动创建和初始化成员:

class Person {
  constructor(
    public name: string,
    private age: number,
    protected email: string
  ) {}
}

// 等价于
class Person {
  public name: string;
  private age: number;
  protected email: string;

  constructor(name: string, age: number, email: string) {
    this.name = name;
    this.age = age;
    this.email = email;
  }
}

存取器 (Getters/Setters)

class Employee {
  private _fullName: string = "";

  get fullName(): string {
    return this._fullName;
  }

  set fullName(newName: string) {
    if (newName && newName.length > 0) {
      this._fullName = newName;
    } else {
      throw new Error("Name cannot be empty");
    }
  }
}

let employee = new Employee();
employee.fullName = "Bob Smith";
console.log(employee.fullName);

静态属性和方法

class Grid {
  static origin = { x: 0, y: 0 };

  static calculateDistance(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);
  }
}

console.log(Grid.origin);
console.log(Grid.calculateDistance({ x: 10, y: 10 }));

抽象类

abstract class Animal {
  abstract makeSound(): void;

  move(): void {
    console.log("Moving...");
  }
}

class Dog extends Animal {
  makeSound() {
    console.log("Woof! Woof!");
  }
}

let dog = new Dog();
dog.makeSound();
dog.move();

let animal = new Animal(); // 错误:不能创建抽象类的实例
类作为接口:

类定义会创建两个东西:类的实例类型和构造函数。因此类也可以当作接口使用。

练习:
  1. 创建一个Person类,包含public的name和private的age
  2. 创建一个Student类继承Person,添加grade属性
  3. 使用参数属性简化类定义
  4. 创建一个抽象类Shape,定义抽象方法getArea()