pablorsk
pablorsk

Reputation: 4296

Create a child instance from parent class in AngularJS+Typescript

How can I create a instance for child class from parent method?

For example:

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

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

Now, I need do this to get a new instance of Car:

Car.getNewInstance();

Vehicle has a many extended classes, and I prevent repeat the code in every child. Also, child classses has more childs too.

Upvotes: 4

Views: 728

Answers (2)

Nitzan Tomer
Nitzan Tomer

Reputation: 164417

Your code won't do it because you want a static method not an instance method.

You can do this:

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;
    }
}

Because Vehicle now has a static getNewInstance method, then all of the extending classes have that as well.
So:

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

Edit

If I misunderstood you and you indeed want to call getNewInstance on an existing instance then you can either do this:

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

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

Or this:

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;
    }
}

Upvotes: 1

iberbeu
iberbeu

Reputation: 16235

Just override getNewInstance in class Car and return a car. Something like

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

Vehicle shouldn't know from Car. So your approach is not very clean.

Anyway it seems that what you are looking for is more a factory than a superclass knowing about its children. I suggest you to implement a factory with methods for returning an instance of each single child. You can then create a method with an input that lets you know which class you want or a method for each single class. The class Vehicle could be the factory itself but I personally don't like that approach

Upvotes: 0

Related Questions