在打字稿中添加抽象子类型 class 的实例

Adding an instance of subtype of abstract class in typescript

我想知道如何实现下面的示例。我试图抽象出 House 的一些核心功能。我运行陷入这种情况。

假设有一个抽象的动物class扩展如下

abstract class Animal{
    constructor(age:number){
        this.age = age;
    }
    age:number;
}
class Dog extends Animal{
    constructor(age:number){
        super(age);
    }
    bark(){
        console.log("Bark");
    }
}

class Cat extends Animal{
    constructor(age:number){
        super(age);
    }
    meow(){
        console.log("Meow");
    }
}

重点是使它成为应用程序的基础 class,许多 class 不同的动物屋扩展了它及其核心功能

abstract class House{
    animals:Animal[];

    addAnimal(humanAge:number){
        const animalAge = humanAge/7;
        // How to add an animal here kind of like animals.push(new Animal(animalAge));
    }
}

class DogHouse extends House{
    doSomethingElseHERE(){
       console.log("Something else")
    }
}

new DogHouse().addAnimal(23); //What would be a viable solution to make this work seamlessly in every animal house like this

那么在抽象中添加函数的一个好的实现是什么class House

您可以使 House 通用,这样元素类型就可以是派生的 classes 中的任何类型的动物,而不是 Animal。此外,如果您需要在基础 class 中创建一个元素,您可以将特定动物的构造函数作为参数传递给基础 class:

abstract class House<T extends Animal>{
    animals: T[];
    constructor(private elementCtor: new (age: number) => T) {

    }

    addAnimal(humanAge: number) {
        const animalAge = humanAge / 7;
        this.animals.push(new this.elementCtor(animalAge));
    }
}

class DogHouse extends House<Dog> {
    constructor() {
        super(Dog)
    }
    doSomethingElseHERE() {
        console.log("Something else")
    }
}

另一种选择是在House中创建一个抽象方法:

abstract class House{
    animals: Animal[];
    constructor() {

    }
    abstract createAnimal(age: number): Animal
    addAnimal(humanAge: number) {
        const animalAge = humanAge / 7;
        this.animals.push(this.createAnimal(animalAge));
    }
}

class DogHouse extends House {
    createAnimal(age: number): Animal {
        return new Dog(age);
    }
    constructor() {
        super()
    }
    doSomethingElseHERE() {
        console.log("Something else")
    }
}