Typescript学习教程,从入门到精通,TypeScript 面向对象编程指南:抽象类、接口及其应用知识点及案例代码(9)

TypeScript 面向对象编程指南:抽象类、接口及其应用

TypeScript 提供了强大的面向对象编程(OOP)特性,包括抽象类、接口及其多继承等高级功能。


一、抽象类(Abstract Classes)

1. 定义与特点

  • 抽象类 是不能被实例化的类,通常用于定义一些通用的属性和方法,供子类继承和实现。
  • 抽象类可以包含抽象方法,这些方法在抽象类中没有具体实现,必须在子类中实现。

2. 语法

abstract class Animal {
  // 抽象属性
  abstract name: string;

  // 抽象方法
  abstract makeSound(): void;

  // 具体方法
  move(): void {
    console.log(`${this.name} is moving.`);
  }
}

3. 使用示例

// 定义一个抽象类 Animal
abstract class Animal {
  // 抽象属性
  abstract name: string;

  // 抽象方法
  abstract makeSound(): void;

  // 具体方法
  move(): void {
    console.log(`${this.name} is moving.`);
  }
}

// 实现抽象类的子类 Dog
class Dog extends Animal {
  name: string;

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

  // 实现抽象方法
  makeSound(): void {
    console.log(`${this.name} says: Woof!`);
  }
}

// 使用示例
const myDog = new Dog("Buddy");
myDog.makeSound(); // 输出: Buddy says: Woof!
myDog.move();      // 输出: Buddy is moving.

二、接口(Interfaces)

1. 定义与特点

  • 接口 是用来定义对象的结构、契约或行为的。它可以包含属性、方法,但不包含具体的实现。
  • 接口可以继承其他接口,实现多重继承。
  • 类可以实现一个或多个接口,必须实现接口中定义的所有成员。

2. 基本语法

interface Person {
  firstName: string;
  lastName: string;
  age?: number; // 可选属性
  greet(): void;
}

3. 使用示例

// 定义接口 Person
interface Person {
  firstName: string;
  lastName: string;
  age?: number; // 可选属性
  greet(): void;
}

// 实现接口的类 Student
class Student implements Person {
  firstName: string;
  lastName: string;
  age: number;

  constructor(firstName: string, lastName: string, age: number) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;
  }

  // 实现接口方法
  greet(): void {
    console.log(`Hello, my name is ${this.firstName} ${this.lastName}.`);
  }
}

// 使用示例
const student = new Student("John", "Doe", 20);
student.greet(); // 输出: Hello, my name is John Doe.

三、接口的多继承(Multiple Inheritance with Interfaces)

1. 概念

TypeScript 不支持类的多重继承,但可以通过接口实现多重继承。一个类可以实现多个接口,从而拥有多个接口定义的行为。

2. 语法

interface Flyable {
  fly(): void;
}

interface Swimmable {
  swim(): void;
}

class Duck implements Flyable, Swimmable {
  fly(): void {
    console.log("The duck is flying.");
  }

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

3. 使用示例

// 定义接口 Flyable 和 Swimmable
interface Flyable {
  fly(): void;
}

interface Swimmable {
  swim(): void;
}

// 实现多个接口的类 Duck
class Duck implements Flyable, Swimmable {
  // 实现 Flyable 接口的方法
  fly(): void {
    console.log("The duck is flying.");
  }

  // 实现 Swimmable 接口的方法
  swim(): void {
    console.log("The duck is swimming.");
  }
}

// 使用示例
const myDuck = new Duck();
myDuck.fly();  // 输出: The duck is flying.
myDuck.swim(); // 输出: The duck is swimming.

四、实战闯关——面向对象编程案例

案例:简单的游戏角色系统

我们将创建一个简单的游戏角色系统,包括不同类型的角色,如战士(Warrior)和法师(Mage),以及一些通用的行为和属性。

1. 定义接口
// 定义接口 Character
interface Character {
  name: string;
  health: number;
  attack(): void;
  defend(): void;
}
2. 定义抽象类
// 定义抽象类 BaseCharacter,实现 Character 接口
abstract class BaseCharacter implements Character {
  name: string;
  health: number;

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

  // 通用方法
  defend(): void {
    console.log(`${this.name} is defending.`);
  }

  // 抽象方法,必须在子类中实现
  abstract attack(): void;
}
3. 实现具体类
// 实现具体类 Warrior,继承自 BaseCharacter
class Warrior extends BaseCharacter {
  weapon: string;

  constructor(name: string, health: number, weapon: string) {
    super(name, health);
    this.weapon = weapon;
  }

  // 实现抽象方法
  attack(): void {
    console.log(`${this.name} attacks with ${this.weapon}.`);
  }

  // 特有方法
  useSpecialAbility(): void {
    console.log(`${this.name} uses the Warrior's special ability: Power Strike!`);
  }
}

// 实现具体类 Mage,继承自 BaseCharacter
class Mage extends BaseCharacter {
  spell: string;

  constructor(name: string, health: number, spell: string) {
    super(name, health);
    this.spell = spell;
  }

  // 实现抽象方法
  attack(): void {
    console.log(`${this.name} casts ${this.spell}.`);
  }

  // 特有方法
  useSpecialAbility(): void {
    console.log(`${this.name} uses the Mage's special ability: Fireball!`);
  }
}
4. 使用示例
// 创建角色实例
const warrior = new Warrior("Aragorn", 100, "Sword");
const mage = new Mage("Gandalf", 80, "Fireball");

// 调用方法
warrior.attack();       // 输出: Aragorn attacks with Sword.
warrior.defend();       // 输出: Aragorn is defending.
warrior.useSpecialAbility(); // 输出: Aragorn uses the Warrior's special ability: Power Strike!

mage.attack();          // 输出: Gandalf casts Fireball.
mage.defend();          // 输出: Gandalf is defending.
mage.useSpecialAbility();    // 输出: Gandalf uses the Mage's special ability: Fireball!
5. 扩展功能:多重继承与接口

假设我们想为角色添加更多的行为,如飞行和游泳,可以使用接口来实现多重继承。

// 定义接口 Flyable 和 Swimmable
interface Flyable {
  fly(): void;
}

interface Swimmable {
  swim(): void;
}

// 修改 Mage 类,使其实现 Flyable 接口
class Mage extends BaseCharacter implements Flyable {
  spell: string;

  constructor(name: string, health: number, spell: string) {
    super(name, health);
    this.spell = spell;
  }

  // 实现抽象方法
  attack(): void {
    console.log(`${this.name} casts ${this.spell}.`);
  }

  // 实现 Flyable 接口的方法
  fly(): void {
    console.log(`${this.name} is flying on a broomstick.`);
  }

  // 特有方法
  useSpecialAbility(): void {
    console.log(`${this.name} uses the Mage's special ability: Fireball!`);
  }
}

// 创建新的 Mage 实例
const mage = new Mage("Gandalf", 80, "Fireball");

// 调用方法
mage.attack();          // 输出: Gandalf casts Fireball.
mage.defend();          // 输出: Gandalf is defending.
mage.fly();             // 输出: Gandalf is flying on a broomstick.
mage.useSpecialAbility(); // 输出: Gandalf uses the Mage's special ability: Fireball!

实战闯关——面向对象

案例:图形计算系统

// 抽象类 - 图形
abstract class Shape {
    // 抽象属性
    abstract name: string;
    
    // 抽象方法 - 计算面积
    abstract calculateArea(): number;
    
    // 抽象方法 - 计算周长
    abstract calculatePerimeter(): number;
    
    // 普通方法
    displayInfo(): void {
        console.log(`Shape: ${this.name}`);
        console.log(`Area: ${this.calculateArea().toFixed(2)}`);
        console.log(`Perimeter: ${this.calculatePerimeter().toFixed(2)}`);
    }
}

// 接口 - 可缩放
interface Scalable {
    scale(factor: number): void;
}

// 接口 - 可移动
interface Movable {
    move(x: number, y: number): void;
}

// 圆形类 - 继承Shape并实现Scalable接口
class Circle extends Shape implements Scalable {
    name: string = 'Circle';
    private radius: number;
    private position: { x: number; y: number } = { x: 0, y: 0 };
    
    constructor(radius: number) {
        super();
        this.radius = radius;
    }
    
    calculateArea(): number {
        return Math.PI * this.radius * this.radius;
    }
    
    calculatePerimeter(): number {
        return 2 * Math.PI * this.radius;
    }
    
    // 实现Scalable接口
    scale(factor: number): void {
        this.radius *= factor;
        console.log(`Circle scaled by factor ${factor}. New radius: ${this.radius}`);
    }
    
    // 添加额外方法
    getRadius(): number {
        return this.radius;
    }
}

// 矩形类 - 继承Shape并实现Scalable和Movable接口
class Rectangle extends Shape implements Scalable, Movable {
    name: string = 'Rectangle';
    private width: number;
    private height: number;
    private position: { x: number; y: number } = { x: 0, y: 0 };
    
    constructor(width: number, height: number) {
        super();
        this.width = width;
        this.height = height;
    }
    
    calculateArea(): number {
        return this.width * this.height;
    }
    
    calculatePerimeter(): number {
        return 2 * (this.width + this.height);
    }
    
    // 实现Scalable接口
    scale(factor: number): void {
        this.width *= factor;
        this.height *= factor;
        console.log(`Rectangle scaled by factor ${factor}. New dimensions: ${this.width}x${this.height}`);
    }
    
    // 实现Movable接口
    move(x: number, y: number): void {
        this.position.x = x;
        this.position.y = y;
        console.log(`Rectangle moved to position (${x}, ${y})`);
    }
    
    // 添加额外方法
    getDimensions(): { width: number; height: number } {
        return { width: this.width, height: this.height };
    }
}

// 使用示例
console.log('=== Circle ===');
const circle = new Circle(5);
circle.displayInfo();
circle.scale(1.5);
circle.displayInfo();

console.log('\n=== Rectangle ===');
const rectangle = new Rectangle(4, 6);
rectangle.displayInfo();
rectangle.scale(0.5);
rectangle.move(10, 20);
rectangle.displayInfo();

// 多态示例
function processShapes(shapes: Shape[]): void {
    console.log('\nProcessing shapes:');
    shapes.forEach(shape => {
        shape.displayInfo();
        if ('scale' in shape) {
            (shape as Scalable).scale(0.8);
            shape.displayInfo();
        }
        if ('move' in shape) {
            (shape as Movable).move(5, 5);
        }
        console.log('---');
    });
}

processShapes([new Circle(3), new Rectangle(2, 4)]);

案例:支付系统

// 支付接口
interface PaymentMethod {
    processPayment(amount: number): boolean;
    getPaymentDetails(): string;
}

// 可退款接口
interface Refundable {
    processRefund(amount: number): boolean;
}

// 可验证接口
interface Verifiable {
    verify(): boolean;
}

// 信用卡支付类
class CreditCardPayment implements PaymentMethod, Verifiable {
    constructor(
        private cardNumber: string,
        private expiryDate: string,
        private cvv: string
    ) {}
    
    processPayment(amount: number): boolean {
        console.log(`Processing credit card payment of $${amount}`);
        // 实际处理逻辑...
        return true;
    }
    
    getPaymentDetails(): string {
        return `Credit Card ending with ${this.cardNumber.slice(-4)}`;
    }
    
    verify(): boolean {
        console.log('Verifying credit card details...');
        // 验证逻辑...
        return this.cardNumber.length === 16 && this.cvv.length === 3;
    }
}

// PayPal支付类
class PayPalPayment implements PaymentMethod, Refundable {
    constructor(private email: string) {}
    
    processPayment(amount: number): boolean {
        console.log(`Processing PayPal payment of $${amount} for ${this.email}`);
        // 实际处理逻辑...
        return true;
    }
    
    getPaymentDetails(): string {
        return `PayPal account: ${this.email}`;
    }
    
    processRefund(amount: number): boolean {
        console.log(`Processing refund of $${amount} to PayPal account ${this.email}`);
        // 退款逻辑...
        return true;
    }
}

// 支付处理器类
class PaymentProcessor {
    process(paymentMethod: PaymentMethod, amount: number): void {
        console.log('\nStarting payment processing...');
        
        // 如果是可验证的支付方式,先验证
        if ('verify' in paymentMethod) {
            const verifiable = paymentMethod as Verifiable;
            if (!verifiable.verify()) {
                console.log('Payment verification failed');
                return;
            }
        }
        
        // 处理支付
        const success = paymentMethod.processPayment(amount);
        if (success) {
            console.log(`Payment successful via ${paymentMethod.getPaymentDetails()}`);
        } else {
            console.log('Payment failed');
        }
    }
    
    refund(refundable: Refundable, amount: number): void {
        console.log('\nStarting refund processing...');
        const success = refundable.processRefund(amount);
        if (success) {
            console.log('Refund processed successfully');
        } else {
            console.log('Refund failed');
        }
    }
}

// 使用示例
const creditCard = new CreditCardPayment('1234567812345678', '12/25', '123');
const paypal = new PayPalPayment('[email protected]');

const processor = new PaymentProcessor();

processor.process(creditCard, 100);
processor.process(paypal, 50);

// 只有PayPal支持退款
processor.refund(paypal, 25);

// 错误 - CreditCardPayment没有实现Refundable接口
// processor.refund(creditCard, 10);

五、总结

通过以上内容,我们了解了 TypeScript 中抽象类和接口的概念及其应用:

  1. 抽象类 提供了定义通用属性和方法的基础,同时强制子类实现抽象方法,适用于需要共享代码但不允许直接实例化的场景。
  2. 接口 定义了对象的行为和结构,支持多重继承,使得类可以实现多个接口,增强了代码的灵活性和可维护性。
  3. 多重继承 通过接口实现,使得一个类可以拥有多个接口定义的行为,适用于需要组合多种行为的场景。

这些特性使得 TypeScript 在大型项目和应用中具有强大的面向对象编程能力,能够帮助开发者构建结构清晰、可扩展性强的代码体系。

你可能感兴趣的:(前端开发,typescript,网页开发,typescript,学习,开发语言,javascript,jquery,前端,html5)