Creează o instanță copil din clasa părinte în AngularJS+Typescript


Cum pot să creez o instanță pentru o clasă copil dintr-o metodă părinte?

De exemplu:

class Vehicle {
    public getNewInstance(): ICar {
        // What should be here? 
        return new XXXXXXXX; 
    }
}

class Car extends Vehicle {
    public getWheels(): Number {
        return 4;
    }
}

Acum, trebuie să fac asta pentru a obține o nouă instanță de Mașină:

Car.getNewInstance();

Vehiculul are multe clase derivate și previn repetarea codului în fiecare copil. De asemenea, clasele copil au și ele mai mulți copii.

Răspuns #1

Codul tău nu va face asta pentru că vrei o metodă statică, nu o metodă de instanță.

Poți face asta:

class Vehicle {
    public static getNewInstance(): Vehicle {
        return new this();
    }

    public getWheels(): Number {
        throw new Error("unknown number of wheels for abstract Vehicle");
    }
}

class Car extends Vehicle {
    public getWheels(): Number {
        return 4;
    }
}

Deoarece Vehicle are acum o metodă statică getNewInstance, atunci toate clasele care îl extind au asta de asemenea.
Deci:

let v = Vehicle.getNewInstance();
console.log(v); // Vehicle {}
console.log(v.getWheels()); // Uncaught Error: unknown number of wheels for abstract Vehicle

let c = Car.getNewInstance();
console.log(c); // Car {}
console.log(c.getWheels()); // 4

Editează

Dacă v-am înțeles greșit și doriți într-adevăr să apelați getNewInstance pe o instanță existentă, atunci puteți face fie asta:

abstract class Vehicle {
    public abstract getNewInstance(): Vehicle;
}

class Car extends Vehicle {
    public getNewInstance(): Vehicle {
        return new Car();
    }
    
    public getWheels(): Number {
        return 4;
    }
}

Sau asta:

class Vehicle {
    private ctor: { new (): Vehicle };
    
    constructor(ctor: { new (): Vehicle }) {
        this.ctor = ctor;
    }
    
    public getNewInstance(): Vehicle {
        return new this.ctor();
    }
}

class Car extends Vehicle {
    constructor() {
        super(Car);
    }
    
    public getWheels(): Number {
        return 4;
    }
}

Răspunsul #2

Doar suprascrie getNewInstance în clasa Car și returnează o mașină. Ceva de genul

class Car extends Vehicle {
    public getNewInstance(): Car {
        return new Car(); 
    }
}

Vehiculul nu ar trebui să știe despre Mașină. Așadar, abordarea ta nu este foarte curată.

Oricum, se pare că ceea ce cauți este mai mult o fabrică decât o superclasă care să știe despre copiii săi. Îți sugerez să implementezi o fabrică cu metode pentru a returna o instanță a fiecărui copil în parte. Poți apoi să creezi o metodă cu un input care să-ți spună ce clasă vrei sau o metodă pentru fiecare clasă în parte. Clasa Vehicle ar putea fi însăși fabrica, dar personal nu-mi place această abordare.