Is it possible to have something like this pseudocode:
abstract class AbstractParent {
protected value: number;
constructor(value: number) {
this.value = value;
}
...
public times(multiplicator: number) {
return new ???(value * multiplicator);
}
}
Which returns a new Foo
for class Foo extends AbstractParent
and a new Bar
for class Bar extends AbstractParent
?
A maintainable way is to keep the times
calculation in the base class, and implement separate create
factory methods inside Foo
and Bar
. This way, the base class is not aware of its extending child classes.
You declare create
as abstract
in AbstractParent
to make sure it will be implemented in all sub classes. The polymorphic this return type ensures for the caller of times
, that the returned instance has the same sub class type (Playground).
abstract class AbstractParent {
protected value: number;
constructor(value: number) {
this.value = value;
}
times(multiplicator: number) {
return this.create(this.value * multiplicator);
}
// factory method creates instances of same polymorphic type (Foo / Bar)
protected abstract create(value: number): this
}
class Foo extends AbstractParent {
create(value: number) {
// Polymorphic this type is Foo here, so it's OK to return a Foo.
// Compiler is not aware of the class context, so we cast.
return new Foo(value) as this
}
}
class Bar extends AbstractParent {
// same as Foo
create(value: number) {
return new Bar(value) as this
}
}
const foo = new Foo(42).times(2) // Foo
const bar = new Bar(42).times(3) // Bar