#javascript #typescript #inheritance
#javascript #typescript #наследование
Вопрос:
У меня есть иерархия наследования, где объекты могут быть либо сконструированы обычным образом с некоторыми значениями и некоторыми значениями по умолчанию, предоставляемыми различными конструкторами, либо могут быть сконструированы из сериализованной формы со всеми предоставленными значениями. Я хотел бы обрабатывать построение из сериализованной формы с помощью статических заводских методов, которые я определяю для каждого класса. Вот так:
class A {
constructor(x: number) {
this.x = x;
}
static fromValues(v: {x: number}) {
return new A(v.x);
}
}
class B extends A {
constructor(y: number) {
super(0);
this.y = y;
}
static fromValues(v: {x: number, y: number}) {
// what goes here
}
}
class C extends B {
constructor(z: number) {
super(0, 1);
this.z = z;
}
static fromValues(v: {x: number, y: number, z: number}) {
// what goes here
}
}
Вопрос в том, как мне реализовать эти методы? Также, предпочтительно, они бы переложили часть работы на статические фабричные методы суперкласса.
Комментарии:
1. Единственный способ, который будет работать так, как написано, — это если вы создадите каждый объект независимо и создадите иерархию вручную, затем установив каждый
__proto__
. Очевидно, что вы не можете создавать экземпляры, используяnew
потому что вы жестко закодировали значения вsuper()
вызовах.2. Итак, я предполагаю, что, возможно, реальный вопрос заключается в следующем: как мне следует обрабатывать этот общий шаблон? (игнорируя пример кода) Даже если я переключу конструктор на принятие сериализованной формы и статические фабрики будут генерировать объекты по умолчанию, я думаю, что я все равно столкнусь с той же проблемой, если я хочу, чтобы значения по умолчанию оставались рядом с классами, к которым они относятся.
3. Пожалуйста, посмотрите мой ответ. Без кода это очень упрямая тема. Но вы увидите, как это работает ниже.
Ответ №1:
Это очень самоуверенная тема (фабрики в JavaScript). Приведенное ниже решение предоставляется «в натуральном виде» (записано как ваш вопрос), чтобы предоставить прямой ответ без мнения о других методах.
Обратите внимание, что типизации удалены из-за ограничения инструмента snippet.
Изменения включают добавление значений по умолчанию в список параметров конструктора. Это позволяет удалить жестко закодированные значения и при необходимости предоставить значения для конструкторов подклассов. Кроме того, в ваших статических методах требуются значения по умолчанию по той же причине.
Это позволяет создавать отдельные объекты или всю иерархию либо с помощью статического фабричного метода, ЛИБО с помощью new
ключевого слова.
class A {
constructor(x = 0) {
this.x = x;
}
static fromValues(v = {x:0}) {
return new A(v.x);
}
}
class B extends A {
constructor(y = 0, x) {
super(x);
this.y = y;
}
static fromValues(v = {y:0, x:0}) {
return new B(v.y, v.x)
}
}
class C extends B {
constructor(z = 0, y, x) {
super(y, x);
this.z = z;
}
static fromValues(v = {z:0, y:0, x:0}) {
return new C(v.z, v.y, v.x);
}
}
const a = A.fromValues({x: 3});
const b = B.fromValues({y: 2,x: 3});
const c = C.fromValues({z: 1,y: 2,x: 3});
const nv = C.fromValues();
console.log("A", a);
console.log("B", b);
console.log("C", c);
console.log("No Values", nv);