Skip to content

TypeScript 面向对象:Class 与 TS

TypeScript 支持面向对象编程,本章节将介绍 TypeScript 中的类(Class)相关特性,包括类的定义、构造函数、修饰符、只读属性、静态属性、类实现接口、抽象类等。

类的定义

使用 class 关键字定义类:

示例:

typescript
// 定义一个类
class Person {
  // 属性
  name: string;
  age: number;

  // 构造函数
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  // 方法
  sayHello(): void {
    console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`);
  }

  // 方法
  getBirthYear(): number {
    const currentYear = new Date().getFullYear();
    return currentYear - this.age;
  }
}

// 创建类的实例
const person = new Person("John", 30);

// 访问属性
console.log(person.name); // John
console.log(person.age); // 30

// 调用方法
person.sayHello(); // Hello, my name is John and I'm 30 years old.
console.log(person.getBirthYear()); // 1994 (假设当前是2024年)

构造函数

构造函数是类的特殊方法,在创建类的实例时自动调用:

示例:

typescript
class Car {
  brand: string;
  model: string;
  year: number;

  // 构造函数
  constructor(brand: string, model: string, year: number) {
    this.brand = brand;
    this.model = model;
    this.year = year;
  }

  // 方法
  getCarInfo(): string {
    return `${this.year} ${this.brand} ${this.model}`;
  }
}

// 创建实例
const car = new Car("Toyota", "Corolla", 2020);
console.log(car.getCarInfo()); // 2020 Toyota Corolla

// 构造函数参数可以有默认值
class Person {
  name: string;
  age: number;

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

const person1 = new Person("John"); // age 默认为 18
const person2 = new Person("Jane", 25); // age 为 25

修饰符

TypeScript 提供了三种访问修饰符:

  • public:公共的,可以在任何地方访问(默认)
  • private:私有的,只能在类内部访问
  • protected:受保护的,可以在类内部和子类中访问

示例:

typescript
class Person {
  // 公共属性
  public name: string;
  
  // 私有属性
  private age: number;
  
  // 受保护属性
  protected gender: string;

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

  // 公共方法
  public sayHello(): void {
    console.log(`Hello, my name is ${this.name}`);
    this.logAge(); // 可以在类内部访问私有方法
  }

  // 私有方法
  private logAge(): void {
    console.log(`I'm ${this.age} years old`);
  }

  // 受保护方法
  protected logGender(): void {
    console.log(`I'm ${this.gender}`);
  }
}

class Employee extends Person {
  constructor(name: string, age: number, gender: string) {
    super(name, age, gender);
  }

  public introduce(): void {
    console.log(`Hi, I'm ${this.name}`);
    // this.logAge(); // 错误:不能访问私有方法
    this.logGender(); // 可以访问受保护方法
  }
}

// 使用
const person = new Person("John", 30, "male");
console.log(person.name); // 正确:可以访问公共属性
// console.log(person.age); // 错误:不能访问私有属性
// console.log(person.gender); // 错误:不能访问受保护属性

person.sayHello(); // 正确:可以调用公共方法
// person.logAge(); // 错误:不能调用私有方法
// person.logGender(); // 错误:不能调用受保护方法

const employee = new Employee("Jane", 25, "female");
employee.introduce(); // 正确:可以调用公共方法

只读属性

使用 readonly 关键字标记只读属性:

示例:

typescript
class Person {
  // 只读属性
  readonly id: number;
  name: string;

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

  // 方法
  updateName(newName: string): void {
    this.name = newName; // 正确:可以修改普通属性
    // this.id = 2; // 错误:不能修改只读属性
  }
}

// 使用
const person = new Person(1, "John");
console.log(person.id); // 1
console.log(person.name); // John

person.updateName("Jane");
console.log(person.name); // Jane
// person.id = 2; // 错误:不能修改只读属性

静态属性

使用 static 关键字定义静态属性和方法:

示例:

typescript
class MathUtil {
  // 静态属性
  static PI: number = 3.14159;

  // 静态方法
  static add(a: number, b: number): number {
    return a + b;
  }

  static multiply(a: number, b: number): number {
    return a * b;
  }
}

// 访问静态属性
console.log(MathUtil.PI); // 3.14159

// 调用静态方法
console.log(MathUtil.add(1, 2)); // 3
console.log(MathUtil.multiply(2, 3)); // 6

// 静态属性和方法也可以有访问修饰符
class Config {
  private static apiKey: string = "secret-key";

  public static getApiKey(): string {
    return this.apiKey;
  }
}

// console.log(Config.apiKey); // 错误:不能访问私有静态属性
console.log(Config.getApiKey()); // secret-key

类实现接口

使用 implements 关键字让类实现接口:

示例:

typescript
// 定义接口
interface Animal {
  name: string;
  makeSound(): void;
}

// 实现接口
class Dog implements Animal {
  name: string;

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

  makeSound(): void {
    console.log("Woof!");
  }
}

class Cat implements Animal {
  name: string;

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

  makeSound(): void {
    console.log("Meow!");
  }
}

// 使用
const dog = new Dog("Rex");
dog.makeSound(); // Woof!

const cat = new Cat("Whiskers");
cat.makeSound(); // Meow!

// 实现多个接口
interface Flyable {
  fly(): void;
}

interface Swimmable {
  swim(): void;
}

class Duck implements Animal, Flyable, Swimmable {
  name: string;

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

  makeSound(): void {
    console.log("Quack!");
  }

  fly(): void {
    console.log("Duck is flying");
  }

  swim(): void {
    console.log("Duck is swimming");
  }
}

const duck = new Duck("Donald");
duck.makeSound(); // Quack!
duck.fly(); // Duck is flying
duck.swim(); // Duck is swimming

抽象类

使用 abstract 关键字定义抽象类:

示例:

typescript
// 定义抽象类
abstract class Shape {
  // 抽象属性
  abstract name: string;

  // 普通方法
  getArea(): number {
    return 0;
  }

  // 抽象方法(必须在子类中实现)
  abstract calculateArea(): number;
}

// 继承抽象类
class Circle extends Shape {
  name: string = "Circle";
  radius: number;

  constructor(radius: number) {
    super();
    this.radius = radius;
  }

  // 实现抽象方法
  calculateArea(): number {
    return Math.PI * this.radius * this.radius;
  }
}

class Rectangle extends Shape {
  name: string = "Rectangle";
  width: number;
  height: number;

  constructor(width: number, height: number) {
    super();
    this.width = width;
    this.height = height;
  }

  // 实现抽象方法
  calculateArea(): number {
    return this.width * this.height;
  }
}

// 使用
const circle = new Circle(5);
console.log(`${circle.name} area: ${circle.calculateArea()}`); // Circle area: 78.53981633974483

const rectangle = new Rectangle(4, 6);
console.log(`${rectangle.name} area: ${rectangle.calculateArea()}`); // Rectangle area: 24

// 不能实例化抽象类
// const shape = new Shape(); // 错误:Cannot create an instance of an abstract class

实战:TS 面向对象案例

示例:学生管理系统

typescript
// 定义接口
interface Person {
  id: number;
  name: string;
  age: number;
}

interface Student extends Person {
  studentId: string;
  grade: string;
  courses: Course[];
  enrollCourse(course: Course): void;
  getGPA(): number;
}

interface Course {
  id: number;
  name: string;
  credits: number;
  grade?: number;
}

// 实现 Course 类
class CourseImpl implements Course {
  id: number;
  name: string;
  credits: number;
  grade?: number;

  constructor(id: number, name: string, credits: number) {
    this.id = id;
    this.name = name;
    this.credits = credits;
  }
}

// 实现 Student 类
class StudentImpl implements Student {
  id: number;
  name: string;
  age: number;
  studentId: string;
  grade: string;
  courses: Course[] = [];

  constructor(id: number, name: string, age: number, studentId: string, grade: string) {
    this.id = id;
    this.name = name;
    this.age = age;
    this.studentId = studentId;
    this.grade = grade;
  }

  enrollCourse(course: Course): void {
    this.courses.push(course);
  }

  getGPA(): number {
    if (this.courses.length === 0) {
      return 0;
    }

    const totalPoints = this.courses.reduce((sum, course) => {
      const grade = course.grade || 0;
      return sum + (grade * course.credits);
    }, 0);

    const totalCredits = this.courses.reduce((sum, course) => {
      return sum + course.credits;
    }, 0);

    return totalPoints / totalCredits;
  }
}

// 使用
const mathCourse = new CourseImpl(1, "Mathematics", 3);
const englishCourse = new CourseImpl(2, "English", 3);
const scienceCourse = new CourseImpl(3, "Science", 4);

const student = new StudentImpl(1, "John", 16, "S12345", "10th Grade");
student.enrollCourse(mathCourse);
student.enrollCourse(englishCourse);
student.enrollCourse(scienceCourse);

// 设置成绩
mathCourse.grade = 95;
englishCourse.grade = 88;
scienceCourse.grade = 92;

console.log(`Student: ${student.name}`);
console.log(`Student ID: ${student.studentId}`);
console.log(`Grade: ${student.grade}`);
console.log(`Courses enrolled: ${student.courses.length}`);
console.log(`GPA: ${student.getGPA().toFixed(2)}`);

小结

本章节介绍了 TypeScript 中的面向对象编程特性,包括:

  • 类的定义
  • 构造函数
  • 修饰符:public / private / protected
  • 只读属性 readonly
  • 静态属性 static
  • 类实现接口 implements
  • 抽象类 abstract
  • 实战:TS 面向对象案例

TypeScript 的面向对象特性可以帮助你构建更结构化、更可维护的代码,特别是在大型项目中。通过使用类、接口、抽象类等特性,你可以创建清晰的代码结构,提高代码的可复用性和可维护性。

在实际开发中,应该根据具体需求选择合适的面向对象特性,以构建高质量的 TypeScript 代码。

© 2026 编程马·菜鸟教程 版权所有