跳至内容
张叶安的小站
用户工具
登录
站点工具
搜索
工具
显示页面
过去修订
反向链接
最近更改
媒体管理器
网站地图
登录
>
最近更改
媒体管理器
网站地图
您的足迹:
typescript:第六章类
本页面只读。您可以查看源文件,但不能更改它。如果您觉得这是系统错误,请联系管理员。
====== 第六章:类 ====== ===== 本章概述 ===== 类是面向对象编程的核心概念。TypeScript 扩展了 JavaScript 的类,添加了类型注解、访问修饰符、抽象类等特性。本章将深入讲解 TypeScript 类的完整功能。 ===== 6.1 类基础 ===== ==== 6.1.1 基本类定义 ==== ```typescript class Person { // 属性声明 name: string; age: number; // 构造函数 constructor(name: string, age: number) { this.name = name; this.age = age; } // 方法 greet(): string { return `Hello, my name is ${this.name}`; } // 获取年龄 getAge(): number { return this.age; } } // 创建实例 const alice = new Person("Alice", 25); console.log(alice.greet()); // "Hello, my name is Alice" ``` ==== 6.1.2 属性简写语法 ==== ```typescript // 使用 public 修饰符简化属性声明 class Person2 { constructor( public name: string, public age: number, private id: string ) {} greet(): string { return `Hello, my name is ${this.name}`; } } const bob = new Person2("Bob", 30, "user-123"); console.log(bob.name); // "Bob" // console.log(bob.id); // Error: 私有属性 ``` ===== 6.2 访问修饰符 ===== ==== 6.2.1 public(默认) ==== ```typescript class Animal { public name: string; // 默认就是 public constructor(name: string) { this.name = name; } public move(distance: number): void { console.log(`${this.name} moved ${distance}m`); } } const dog = new Animal("Dog"); console.log(dog.name); // OK dog.move(10); // OK ``` ==== 6.2.2 private ==== ```typescript class BankAccount { private balance: number = 0; private readonly accountId: string; constructor(accountId: string, initialBalance: number) { this.accountId = accountId; this.balance = initialBalance; } deposit(amount: number): void { if (amount > 0) { this.balance += amount; } } withdraw(amount: number): boolean { if (amount > 0 && this.balance >= amount) { this.balance -= amount; return true; } return false; } getBalance(): number { return this.balance; } } const account = new BankAccount("ACC-001", 1000); account.deposit(500); console.log(account.getBalance()); // 1500 // console.log(account.balance); // Error: 私有属性 // account.balance = 1000000; // Error ``` ==== 6.2.3 protected ==== ```typescript class Vehicle { protected brand: string; protected speed: number = 0; constructor(brand: string) { this.brand = brand; } protected accelerate(amount: number): void { this.speed += amount; } getSpeed(): number { return this.speed; } } class Car extends Vehicle { private model: string; constructor(brand: string, model: string) { super(brand); this.model = model; } speedUp(): void { // 可以访问父类的 protected 成员 this.accelerate(10); console.log(`${this.brand} ${this.model} speeding up to ${this.speed}km/h`); } } const car = new Car("Toyota", "Camry"); car.speedUp(); // OK // car.accelerate(20); // Error: 受保护的方法 // car.brand; // Error: 受保护的属性 ``` ==== 6.2.4 readonly ==== ```typescript class Employee { readonly id: string; name: string; readonly hireDate: Date; constructor(id: string, name: string) { this.id = id; this.name = name; this.hireDate = new Date(); } // 不能在方法中修改 readonly 属性 // updateId(newId: string): void { // this.id = newId; // Error // } } const emp = new Employee("E001", "Alice"); console.log(emp.id); // emp.id = "E002"; // Error ``` ===== 6.3 继承 ===== ==== 6.3.1 extends 关键字 ==== ```typescript class Animal { protected name: string; constructor(name: string) { this.name = name; } move(distance: number = 0): void { console.log(`${this.name} moved ${distance}m`); } makeSound(): void { console.log("Some sound"); } } class Dog extends Animal { private breed: string; constructor(name: string, breed: string) { super(name); // 必须调用父类构造函数 this.breed = breed; } // 重写方法 makeSound(): void { console.log("Woof! Woof!"); } fetch(): void { console.log(`${this.name} is fetching the ball`); } getBreed(): string { return this.breed; } } const dog = new Dog("Buddy", "Golden Retriever"); dog.move(10); // 继承的方法 dog.makeSound(); // 重写的方法 dog.fetch(); // 子类的方法 ``` ==== 6.3.2 super 关键字 ==== ```typescript class Rectangle { constructor( protected width: number, protected height: number ) {} getArea(): number { return this.width * this.height; } describe(): string { return `Rectangle: ${this.width}x${this.height}`; } } class Square extends Rectangle { constructor(side: number) { super(side, side); // 调用父类构造函数 } describe(): string { // 调用父类方法 const baseDescription = super.describe(); return `${baseDescription} (Square)`; } } const square = new Square(5); console.log(square.getArea()); // 25 console.log(square.describe()); // "Rectangle: 5x5 (Square)" ``` ==== 6.3.3 方法重写与重载 ==== ```typescript class Person { constructor(protected name: string) {} introduce(): string { return `I am ${this.name}`; } } class Student extends Person { constructor( name: string, private grade: number ) { super(name); } // 方法重写 introduce(): string { const base = super.introduce(); return `${base}, a student in grade ${this.grade}`; } } // 方法重载 class Calculator { add(a: number, b: number): number; add(a: string, b: string): string; add(a: any, b: any): any { if (typeof a === "number" && typeof b === "number") { return a + b; } return String(a) + String(b); } } const calc = new Calculator(); console.log(calc.add(1, 2)); // 3 console.log(calc.add("a", "b")); // "ab" ``` ===== 6.4 抽象类 ===== ==== 6.4.1 abstract 关键字 ==== ```typescript // 抽象类不能实例化 abstract class Shape { protected color: string; constructor(color: string) { this.color = color; } // 抽象方法必须在子类中实现 abstract getArea(): number; abstract getPerimeter(): number; // 普通方法 describe(): string { return `A ${this.color} shape`; } } // 具体类必须实现所有抽象方法 class Circle extends Shape { constructor( color: string, private radius: number ) { super(color); } getArea(): number { return Math.PI * this.radius ** 2; } getPerimeter(): number { return 2 * Math.PI * this.radius; } } class Rectangle extends Shape { constructor( color: string, private width: number, private height: number ) { super(color); } getArea(): number { return this.width * this.height; } getPerimeter(): number { return 2 * (this.width + this.height); } } // 使用 const shapes: Shape[] = [ new Circle("red", 5), new Rectangle("blue", 4, 6) ]; shapes.forEach(shape => { console.log(`${shape.describe()}: Area=${shape.getArea().toFixed(2)}`); }); // 抽象类不能实例化 // const shape = new Shape("green"); // Error ``` ===== 6.5 存取器(Getters 和 Setters) ===== ==== 6.5.1 基本使用 ==== ```typescript class Employee { private _name: string; private _salary: number; constructor(name: string, salary: number) { this._name = name; this._salary = salary; } // getter get name(): string { return this._name; } // setter set name(value: string) { if (value.length < 2) { throw new Error("Name must be at least 2 characters"); } this._name = value; } get salary(): number { return this._salary; } // 只读属性(只有 getter) get annualSalary(): number { return this._salary * 12; } } const emp = new Employee("Alice", 5000); console.log(emp.name); // "Alice" emp.name = "Bob"; // 使用 setter console.log(emp.annualSalary); // 60000 // emp.salary = 6000; // Error: 没有 setter ``` ==== 6.5.2 计算属性 ==== ```typescript class Temperature { private _celsius: number; constructor(celsius: number) { this._celsius = celsius; } get celsius(): number { return this._celsius; } set celsius(value: number) { this._celsius = value; } get fahrenheit(): number { return (this._celsius * 9 / 5) + 32; } set fahrenheit(value: number) { this._celsius = (value - 32) * 5 / 9; } get kelvin(): number { return this._celsius + 273.15; } } const temp = new Temperature(25); console.log(temp.fahrenheit); // 77 console.log(temp.kelvin); // 298.15 temp.fahrenheit = 100; console.log(temp.celsius); // 37.777... ``` ===== 6.6 静态成员 ===== ==== 6.6.1 静态属性和方法 ==== ```typescript class MathUtils { // 静态属性 static readonly PI: number = 3.14159; static readonly E: number = 2.71828; // 静态方法 static circleArea(radius: number): number { return this.PI * radius * radius; } static max(a: number, b: number): number { return a > b ? a : b; } // 静态工厂方法 static createRandom(): number { return Math.random(); } } // 无需实例化即可使用 console.log(MathUtils.PI); console.log(MathUtils.circleArea(5)); console.log(MathUtils.max(10, 20)); // 不能通过实例访问 // const utils = new MathUtils(); // utils.PI; // Error ``` ==== 6.6.2 单例模式 ==== ```typescript class Database { private static instance: Database; private connection: string; private constructor(connectionString: string) { this.connection = connectionString; } static getInstance(connectionString: string): Database { if (!Database.instance) { Database.instance = new Database(connectionString); } return Database.instance; } query(sql: string): any { console.log(`Executing: ${sql}`); return []; } } // 使用 const db1 = Database.getInstance("mysql://localhost"); const db2 = Database.getInstance("mysql://remote"); // 返回同一个实例 console.log(db1 === db2); // true ``` ===== 6.7 类与接口 ===== ==== 6.7.1 类实现接口 ==== ```typescript interface Printable { print(): void; } interface Loggable { log(): void; } // 类可以实现多个接口 class Document implements Printable, Loggable { constructor(private content: string) {} print(): void { console.log("Printing:", this.content); } log(): void { console.log("Logging document content"); } } ``` ==== 6.7.2 接口继承类 ==== ```typescript class Point { x: number; y: number; constructor(x: number, y: number) { this.x = x; this.y = y; } } // 接口继承类 interface Point3D extends Point { z: number; } const point3d: Point3D = { x: 1, y: 2, z: 3 }; ``` ===== 6.8 高级类特性 ===== ==== 6.8.1 泛型类 ==== ```typescript class GenericStack<T> { private items: T[] = []; push(item: T): void { this.items.push(item); } pop(): T | undefined { return this.items.pop(); } peek(): T | undefined { return this.items[this.items.length - 1]; } isEmpty(): boolean { return this.items.length === 0; } size(): number { return this.items.length; } } // 使用 const numberStack = new GenericStack<number>(); numberStack.push(1); numberStack.push(2); console.log(numberStack.pop()); // 2 const stringStack = new GenericStack<string>(); stringStack.push("hello"); stringStack.push("world"); console.log(stringStack.pop()); // "world" ``` ==== 6.8.2 抽象属性 ==== ```typescript abstract class Component { abstract id: string; // 抽象属性 abstract render(): void; mount(): void { console.log(`Mounting component ${this.id}`); this.render(); } } class ButtonComponent extends Component { id: string = "button-" + Math.random().toString(36); render(): void { console.log("Rendering button"); } } ``` ===== 6.9 本章小结 ===== 本章我们学习了: 1. **类基础** - 属性声明、构造函数、方法 2. **访问修饰符** - public、private、protected、readonly 3. **继承** - extends、super、方法重写 4. **抽象类** - abstract、抽象方法 5. **存取器** - getter 和 setter 6. **静态成员** - 静态属性、静态方法、单例模式 7. **类与接口** - 类实现接口、接口继承类 8. **泛型类** - 类型参数化 ===== 6.10 练习题 ===== ==== 练习 1:实现银行账户类 ==== 设计一个 BankAccount 类,要求: - 私有属性:balance(余额)、accountNumber(账号)、ownerName(所有者) - 公共方法:deposit(存款)、withdraw(取款)、getBalance(查询余额) - 取款时检查余额是否充足 - 使用 getter 获取账户信息 <details> <summary>参考答案</summary> ```typescript class BankAccount { private _balance: number = 0; private readonly _accountNumber: string; private readonly _ownerName: string; private _transactionHistory: string[] = []; constructor(accountNumber: string, ownerName: string, initialBalance: number = 0) { this._accountNumber = accountNumber; this._ownerName = ownerName; this._balance = initialBalance; this._logTransaction("ACCOUNT_OPENED", initialBalance); } get accountNumber(): string { return this._accountNumber; } get ownerName(): string { return this._ownerName; } get balance(): number { return this._balance; } get transactionHistory(): readonly string[] { return [...this._transactionHistory]; } deposit(amount: number): void { if (amount <= 0) { throw new Error("Deposit amount must be positive"); } this._balance += amount; this._logTransaction("DEPOSIT", amount); } withdraw(amount: number): void { if (amount <= 0) { throw new Error("Withdrawal amount must be positive"); } if (amount > this._balance) { throw new Error("Insufficient funds"); } this._balance -= amount; this._logTransaction("WITHDRAWAL", amount); } transfer(amount: number, targetAccount: BankAccount): void { this.withdraw(amount); targetAccount.deposit(amount); this._logTransaction(`TRANSFER_TO_${targetAccount.accountNumber}`, amount); } private _logTransaction(type: string, amount: number): void { const timestamp = new Date().toISOString(); this._transactionHistory.push( `[${timestamp}] ${type}: $${amount.toFixed(2)}, Balance: $${this._balance.toFixed(2)}` ); } } // 使用 const account1 = new BankAccount("ACC-001", "Alice", 1000); const account2 = new BankAccount("ACC-002", "Bob", 500); account1.deposit(500); account1.transfer(200, account2); console.log(account1.balance); // 1300 console.log(account2.balance); // 700 console.log(account1.transactionHistory); ``` </details> ==== 练习 2:实现图形类层次结构 ==== 设计一个图形类系统,要求: - 抽象基类 Shape,包含 color 属性和抽象方法 getArea()、getPerimeter() - 具体类:Circle、Rectangle、Triangle - 每个类有自己的属性(radius、width/height、sides) - 实现静态工厂方法 <details> <summary>参考答案</summary> ```typescript abstract class Shape { constructor(protected color: string) {} abstract getArea(): number; abstract getPerimeter(): number; abstract describe(): string; getColor(): string { return this.color; } setColor(color: string): void { this.color = color; } } class Circle extends Shape { constructor(color: string, private radius: number) { super(color); if (radius <= 0) { throw new Error("Radius must be positive"); } } getArea(): number { return Math.PI * this.radius ** 2; } getPerimeter(): number { return 2 * Math.PI * this.radius; } describe(): string { return `Circle(${this.radius}) - ${this.color}`; } getRadius(): number { return this.radius; } setRadius(radius: number): void { if (radius <= 0) { throw new Error("Radius must be positive"); } this.radius = radius; } } class Rectangle extends Shape { constructor( color: string, private width: number, private height: number ) { super(color); if (width <= 0 || height <= 0) { throw new Error("Dimensions must be positive"); } } getArea(): number { return this.width * this.height; } getPerimeter(): number { return 2 * (this.width + this.height); } describe(): string { return `Rectangle(${this.width}x${this.height}) - ${this.color}`; } isSquare(): boolean { return this.width === this.height; } } class Triangle extends Shape { constructor( color: string, private a: number, private b: number, private c: number ) { super(color); // 验证三角形不等式 if (a + b <= c || a + c <= b || b + c <= a) { throw new Error("Invalid triangle sides"); } } getArea(): number { // 海伦公式 const s = this.getPerimeter() / 2; return Math.sqrt(s * (s - this.a) * (s - this.b) * (s - this.c)); } getPerimeter(): number { return this.a + this.b + this.c; } describe(): string { return `Triangle(${this.a}, ${this.b}, ${this.c}) - ${this.color}`; } } // 形状工厂 class ShapeFactory { static createCircle(color: string, radius: number): Circle { return new Circle(color, radius); } static createRectangle(color: string, width: number, height: number): Rectangle { return new Rectangle(color, width, height); } static createTriangle(color: string, a: number, b: number, c: number): Triangle { return new Triangle(color, a, b, c); } static createRandomShape(): Shape { const shapes = ["circle", "rectangle", "triangle"]; const randomShape = shapes[Math.floor(Math.random() * shapes.length)]; const color = ["red", "blue", "green"][Math.floor(Math.random() * 3)]; switch (randomShape) { case "circle": return new Circle(color, Math.random() * 10 + 1); case "rectangle": return new Rectangle(color, Math.random() * 10 + 1, Math.random() * 10 + 1); case "triangle": return new Triangle(color, 3, 4, 5); default: throw new Error("Unknown shape"); } } } // 使用 const shapes: Shape[] = [ ShapeFactory.createCircle("red", 5), ShapeFactory.createRectangle("blue", 4, 6), ShapeFactory.createTriangle("green", 3, 4, 5) ]; shapes.forEach(shape => { console.log(`${shape.describe()}`); console.log(` Area: ${shape.getArea().toFixed(2)}`); console.log(` Perimeter: ${shape.getPerimeter().toFixed(2)}`); }); ``` </details> ==== 练习 3:实现泛型集合类 ==== 实现一个泛型的 Collection 类,要求: - 支持添加、删除、查询元素 - 支持过滤、映射、归约操作 - 支持迭代器 <details> <summary>参考答案</summary> ```typescript class Collection<T> implements Iterable<T> { private items: T[] = []; add(item: T): void { this.items.push(item); } remove(item: T): boolean { const index = this.items.indexOf(item); if (index > -1) { this.items.splice(index, 1); return true; } return false; } removeAt(index: number): T | undefined { if (index < 0 || index >= this.items.length) { return undefined; } return this.items.splice(index, 1)[0]; } get(index: number): T | undefined { return this.items[index]; } contains(item: T): boolean { return this.items.includes(item); } size(): number { return this.items.length; } isEmpty(): boolean { return this.items.length === 0; } clear(): void { this.items = []; } toArray(): T[] { return [...this.items]; } // 高阶函数 filter(predicate: (item: T) => boolean): Collection<T> { const result = new Collection<T>(); for (const item of this.items) { if (predicate(item)) { result.add(item); } } return result; } map<U>(transform: (item: T) => U): Collection<U> { const result = new Collection<U>(); for (const item of this.items) { result.add(transform(item)); } return result; } reduce<U>(reducer: (acc: U, item: T) => U, initial: U): U { let accumulator = initial; for (const item of this.items) { accumulator = reducer(accumulator, item); } return accumulator; } find(predicate: (item: T) => boolean): T | undefined { return this.items.find(predicate); } every(predicate: (item: T) => boolean): boolean { return this.items.every(predicate); } some(predicate: (item: T) => boolean): boolean { return this.items.some(predicate); } // 实现迭代器 [Symbol.iterator](): Iterator<T> { let index = 0; const items = this.items; return { next(): IteratorResult<T> { if (index < items.length) { return { value: items[index++], done: false }; } return { value: undefined as any, done: true }; } }; } // 排序 sort(compareFn?: (a: T, b: T) => number): Collection<T> { const result = new Collection<T>(); result.items = [...this.items].sort(compareFn); return result; } // 反转 reverse(): Collection<T> { const result = new Collection<T>(); result.items = [...this.items].reverse(); return result; } } // 使用 const numbers = new Collection<number>(); numbers.add(5); numbers.add(2); numbers.add(8); numbers.add(1); console.log([...numbers]); // [5, 2, 8, 1] const evens = numbers.filter(n => n % 2 === 0); console.log([...evens]); // [2, 8] const doubled = numbers.map(n => n * 2); console.log([...doubled]); // [10, 4, 16, 2] const sum = numbers.reduce((acc, n) => acc + n, 0); console.log(sum); // 16 const sorted = numbers.sort((a, b) => a - b); console.log([...sorted]); // [1, 2, 5, 8] ``` </details> ===== 扩展阅读 ===== - [[TypeScript:第七章_泛型|下一章:泛型]] - [[https://www.typescriptlang.org/docs/handbook/2/classes.html|TypeScript 官方文档 - 类]]
typescript/第六章类.txt
· 最后更改:
2026/02/03 19:45
由
127.0.0.1
页面工具
显示页面
过去修订
反向链接
回到顶部