TypeScript - 泛型类



泛型类

TypeScript 泛型类允许你创建一个可以处理多种数据类型而不是单一数据类型的类。它提高了代码的可扩展性和可重用性。让我们了解 TypeScript 中泛型类的工作原理。

语法

你可以遵循以下语法在 TypeScript 中使用泛型类。

class class_name<T, U> {
    // Class body
}
let obj1 = new class_name<data_type_1, data_type_2>();
  • 在上述语法中,“class”是定义类的关键字。

  • “class_name”是一个有效的标识符,代表类名。

  • “<T, U>”是在尖括号中指定的类型参数。你可以根据需要指定多个。

  • 在定义类的对象时,需要在类名后的尖括号中传递数据类型作为参数。

示例

在下面的代码中,我们定义了一个名为“Box”的泛型类,它接受类型参数 T。

在类中,我们定义了类型为 T 的“val”变量,以及初始化“val”变量值的构造函数。

之后,我们分别定义了名为 get() 和 set() 的 getter 和 setter 方法,用于获取“val”变量的值。

接下来,我们定义了 Box 类的“box1”和“box2”对象,它们分别将数字和字符串数据类型作为类型参数。

// generic class
class Box<T> {
    // member variable
    val: T;

    // constructor with value
    constructor(value: T) {
        this.val = value;
    }

    // Method to get value
    get(): T {
        return this.val;
    }

    // Method to set value
    set(value: T): void {
        this.val = value;
    }
}

// create object of Box class
let box1 = new Box<number>(10);
console.log(box1.get()); // 10

let box2 = new Box<string>("Hello");
console.log(box2.get()); // Hello

编译后,它将生成以下 JavaScript 代码

// generic class
class Box {
    // constructor with value
    constructor(value) {
        this.val = value;
    }
    // Method to get value
    get() {
        return this.val;
    }
    // Method to set value
    set(value) {
        this.val = value;
    }
}
// create object of Box class
let box1 = new Box(10);
console.log(box1.get()); // 10
let box2 = new Box("Hello");
console.log(box2.get()); // Hello

输出

上述代码的输出如下:

10
Hello

示例

在下面的 TypeScript 代码中

  • 我们定义了接受类型参数“T”的“Stack”类。

  • 在类中,我们定义了私有变量“st”,其类型为 T 类型数组。

  • 构造函数初始化“st”数组。

  • push() 方法接受类型为“T”的元素作为参数,并将其插入到“st”数组中。

  • pop() 方法从“st”数组中移除最后一个元素并返回它。

  • peek() 方法返回数组中的最后一个元素。

  • isEmpty() 方法根据数组是否为空返回布尔值。

  • size() 方法返回“st”数组的大小。

  • 接下来,我们使用数字数据类型定义了 Stack 类的对象,并使用 Stack 类的各种方法执行各种操作。

// Defining the class stack
class Stack<T> {
    // Defining the private array to store the stack elements
    private st: T[] = [];

    // Constructor to initialize the stack with initial contents
    constructor(initialContents?: T[]) {
        if (initialContents) {
            this.st = initialContents;
        }
    }

    // Method to push an element to the stack
    push(item: T): void {
        this.st.push(item);
    }

    // Method to pop an element from the stack
    pop(): T | undefined {
        return this.st.pop();
    }

    // Method to get the top element of the stack
    peek(): T | undefined {
        return this.st[this.st.length - 1];
    }

    // Method to check if the stack is empty
    isEmpty(): boolean {
        return this.st.length === 0;
    }

    // Method to get the size of the stack
    size(): number {
        return this.st.length;
    }
}

// Usage Example
const numberStack = new Stack<number>();
numberStack.push(1);
numberStack.push(2);
numberStack.push(3);

console.log(numberStack.peek());  // Outputs: 3
console.log(numberStack.pop());   // Outputs: 3
console.log(numberStack.peek());  // Outputs: 2
console.log(numberStack.isEmpty()); // Outputs: false
console.log(numberStack.size());    // Outputs: 2

编译后,它将生成以下 JavaScript 代码

// Defining the class stack
class Stack {
    // Constructor to initialize the stack with initial contents
    constructor(initialContents) {
        // Defining the private array to store the stack elements
        this.st = [];
        if (initialContents) {
            this.st = initialContents;
        }
    }
    // Method to push an element to the stack
    push(item) {
        this.st.push(item);
    }
    // Method to pop an element from the stack
    pop() {
        return this.st.pop();
    }
    // Method to get the top element of the stack
    peek() {
        return this.st[this.st.length - 1];
    }
    // Method to check if the stack is empty
    isEmpty() {
        return this.st.length === 0;
    }
    // Method to get the size of the stack
    size() {
        return this.st.length;
    }
}
// Usage Example
const numberStack = new Stack();
numberStack.push(1);
numberStack.push(2);
numberStack.push(3);
console.log(numberStack.peek()); // Outputs: 3
console.log(numberStack.pop()); // Outputs: 3
console.log(numberStack.peek()); // Outputs: 2
console.log(numberStack.isEmpty()); // Outputs: false
console.log(numberStack.size()); // Outputs: 2

输出

上述代码的输出如下:

3
3
2
false
2

使用泛型类实现泛型接口

泛型类也可以实现泛型接口。因此,开发人员可以使用单个泛型接口来实现多个泛型类,从而实现代码重用。

语法

你可以遵循以下语法来使用泛型类实现泛型接口。

class class_name<T> implements interface_name<T> {
    // Class body
}
  • 在上述语法中,“class class_name<T>”定义了泛型类。

  • “implements”是使用类实现接口的关键字。

  • “interface_name<T>”是一个泛型接口。

示例

在下面的例子中

  • 我们定义了一个名为“dataBase”的泛型接口,它定义了 findById() 和 save() 方法。

  • 接下来,我们定义了一个名为“memorydataBase”的泛型类,并使用“dataBase”接口实现它。

  • 在类中,我们定义了“items”映射,它存储数字值作为键,类型为“T”的值。

  • 接下来,我们实现了 findById() 方法,它从映射中按键访问值并返回它。

  • save() 方法将键值对存储在“items”映射中。

  • 最后,我们创建了“MemorydataBase”类的对象,并使用此方法执行各种操作。

// Defining a generic interface
interface dataBase<T> {
    findById(id: number): T | undefined;
    save(item: T): void;
}

// Defining a class that implements the generic interface
class MemorydataBase<T> implements dataBase<T> {
    // Defining a private property that is a map of items
    private items = new Map<number, T>();

    // Implementing the findById method
    findById(id: number): T | undefined {
        return this.items.get(id);
    }

    // Implementing the save method
    save(item: T): void {
        const id = this.items.size + 1;
        this.items.set(id, item);
    }
}

// Creating an instance of the MemorydataBase class
const repo = new MemorydataBase<string>();
repo.save("Hello");
console.log(repo.findById(1)); // Outputs: Hello

编译后,它将生成以下 JavaScript 代码

// Defining a class that implements the generic interface
class MemorydataBase {
    constructor() {
        // Defining a private property that is a map of items
        this.items = new Map();
    }
    // Implementing the findById method
    findById(id) {
        return this.items.get(id);
    }
    // Implementing the save method
    save(item) {
        const id = this.items.size + 1;
        this.items.set(id, item);
    }
}
// Creating an instance of the MemorydataBase class
const repo = new MemorydataBase();
repo.save("Hello");
console.log(repo.findById(1)); // Outputs: Hello

输出

上述代码的输出如下:

Hello

你可以使用“extends”关键字在泛型类中使用各种约束。始终建议在代码中使用泛型参数、约束、接口和类,以使其可扩展和可重用。

广告
© . All rights reserved.