TypeScript 类知识点汇总
面向编程小白的详细指南 – 大白话解析TypeScript类核心概念
1什么是类?
类就像是创建对象的”蓝图”或”模具”,它定义了对象应该有哪些属性(特征)和方法(能力)。
例如:
- 汽车类:有颜色、品牌等属性,有启动、加速等方法
- 用户类:有姓名、年龄等属性,有登录、注销等方法
📝代码示例
class Car { // 属性:描述特征 brand: string; color: string; // 构造方法:创建对象时初始化 constructor(brand: string, color: string) { this.brand = brand; this.color = color; } // 方法:对象的行为 drive(): void { console.log(`The ${this.color} ${this.brand} is driving.`); } } // 使用类创建对象 const myCar = new Car("Toyota", "red"); myCar.drive(); // 输出: The red Toyota is driving.
2构造函数与实例化
constructor 是类的特殊方法,在创建新对象时自动调用,用于初始化对象属性。
使用 new 关键字创建类的实例(对象):
- 分配内存空间
- 调用构造函数初始化对象
- 返回新创建的对象
📝代码示例
class User { name: string; age: number; // 构造函数 constructor(name: string, age: number) { this.name = name; this.age = age; console.log(`User ${name} created!`); } greet() { console.log(`Hello, I'm ${this.name}, ${this.age} years old.`); } } // 创建实例 const user1 = new User("Alice", 30); // 输出: User Alice created! user1.greet(); // 输出: Hello, I'm Alice, 30 years old.
3访问修饰符
访问修饰符控制类成员的访问权限:
- public:默认值,任何地方都可以访问
- private:只能在类内部访问
- protected:类内部和子类中可以访问
合理使用访问修饰符可以实现封装,保护类的内部实现细节。
📝代码示例
class BankAccount { public accountNumber: string; // 公开属性 private balance: number; // 私有属性 protected ownerName: string; // 受保护属性 constructor(accountNumber: string, owner: string) { this.accountNumber = accountNumber; this.balance = 0; this.ownerName = owner; } // 公开方法访问私有属性 public deposit(amount: number): void { if (amount > 0) { this.balance += amount; } } public getBalance(): number { return this.balance; // 可以访问私有属性 } } const account = new BankAccount("12345", "Bob"); account.deposit(100); console.log(account.getBalance()); // 输出: 100 // account.balance = 1000; // 错误: 私有属性不能在类外部访问 // account.ownerName = "Alice"; // 错误: 受保护属性不能在类外部访问
4继承与super关键字
继承 允许创建新类(子类)基于现有类(父类):
- 子类继承父类的属性和方法
- 子类可以添加新的属性和方法
- 子类可以重写(覆盖)父类的方法
super 关键字用于调用父类的构造函数或方法。
📝代码示例
class Animal { protected name: string; constructor(name: string) { this.name = name; } move(distance: number = 0) { console.log(`${this.name} moved ${distance}m.`); } } // Dog类继承Animal类 class Dog extends Animal { private breed: string; constructor(name: string, breed: string) { super(name); // 调用父类构造函数 this.breed = breed; } // 重写父类方法 move(distance: number = 5) { console.log('Running...'); super.move(distance); // 调用父类方法 } bark() { console.log('Woof! Woof!'); } } const myDog = new Dog('Rex', 'Labrador'); myDog.bark(); // 输出: Woof! Woof! myDog.move(); // 输出: Running... Rex moved 5m.
5Getter和Setter
Getter和Setter是特殊的类方法:
- Getter:访问属性时调用的方法(获取值)
- Setter:设置属性时调用的方法(设置值)
它们允许你在读取或设置属性时执行额外逻辑,如验证输入值。
📝代码示例
class Person { private _age: number; private _firstName: string; private _lastName: string; constructor(firstName: string, lastName: string, age: number) { this._firstName = firstName; this._lastName = lastName; this._age = age; } // Getter:获取全名 get fullName(): string { return `${this._firstName} ${this._lastName}`; } // Setter:设置年龄(带验证) set age(newAge: number) { if (newAge < 0 || newAge > 120) { throw new Error('Invalid age!'); } this._age = newAge; } // Getter:获取年龄 get age(): number { return this._age; } } const person = new Person('John', 'Doe', 25); console.log(person.fullName); // 输出: John Doe(调用getter) console.log(person.age); // 输出: 25 person.age = 26; // 调用setter console.log(person.age); // 输出: 26 // person.age = -5; // 会抛出错误: Invalid age!
6静态成员
静态成员 属于类本身,而不是类的实例:
- 使用 static 关键字声明
- 通过类名直接访问,不需要创建实例
- 常用于工具方法或共享数据
📝代码示例
class MathHelper { // 静态属性 static PI: number = 3.14159; // 静态方法:计算圆面积 static circleArea(radius: number): number { return this.PI * radius * radius; } // 静态方法:生成随机数 static getRandomNumber(min: number, max: number): number { return Math.floor(Math.random() * (max - min + 1)) + min; } } // 使用静态成员(不需要创建实例) console.log(MathHelper.PI); // 输出: 3.14159 console.log(MathHelper.circleArea(5)); // 输出: 78.53975 const randomNum = MathHelper.getRandomNumber(1, 100); console.log(`随机数: ${randomNum}`);
7抽象类
抽象类 不能被实例化,只能作为其他类的基类:
- 使用 abstract 关键字声明
- 可以包含抽象方法(只有声明,没有实现)
- 子类必须实现所有抽象方法
- 用于定义通用接口和部分实现
📝代码示例
// 抽象类 abstract class Shape { protected color: string; constructor(color: string) { this.color = color; } // 抽象方法:必须由子类实现 abstract getArea(): number; // 普通方法 displayColor(): void { console.log(`This shape is ${this.color}`); } } // 具体子类:圆形 class Circle extends Shape { private radius: number; constructor(color: string, radius: number) { super(color); this.radius = radius; } // 实现抽象方法 getArea(): number { return Math.PI * this.radius * this.radius; } } // 具体子类:矩形 class Rectangle extends Shape { private width: number; private height: number; constructor(color: string, width: number, height: number) { super(color); this.width = width; this.height = height; } // 实现抽象方法 getArea(): number { return this.width * this.height; } } // 使用具体类 const circle = new Circle("red", 5); console.log(circle.getArea()); // 输出: ~78.54 const rectangle = new Rectangle("blue", 4, 6); console.log(rectangle.getArea()); // 输出: 24 // const shape = new Shape("green"); // 错误:无法创建抽象类的实例
8类的高级特性
TypeScript类还提供了一些高级特性:
- 只读属性:只能在声明时或构造函数中初始化
- 接口实现:类可以实现多个接口
- 方法重载:同一个方法名多个不同参数类型
- 类作为接口:类定义创建类型
📝代码示例
// 只读属性 class Employee { readonly id: number; // 只读属性 name: string; constructor(id: number, name: string) { this.id = id; this.name = name; } } const emp = new Employee(1, "Alice"); // emp.id = 2; // 错误:无法分配到"id",因为它是只读属性 // 类实现接口 interface ClockInterface { currentTime: Date; setTime(d: Date): void; } class Clock implements ClockInterface { currentTime: Date = new Date(); setTime(d: Date) { this.currentTime = d; } getTime() { return this.currentTime.toLocaleTimeString(); } } const myClock = new Clock(); console.log(myClock.getTime()); myClock.setTime(new Date("2023-01-01T12:00:00")); console.log(myClock.getTime());
类和面向对象编程的优势
💡
代码组织
将数据和操作数据的方法组织在一起,结构更清晰
🛡️
封装性
隐藏内部实现细节,只暴露必要接口,提高安全性
🧬
继承性
通过继承复用已有代码,减少重复,提高开发效率
🌀
多态性
同一操作作用于不同对象可以有不同的解释和执行结果
🧱
模块化
类作为独立的模块,便于维护和代码复用
📈
可扩展性
通过继承和组合,可以轻松扩展功能