是否可能有这样的伪代码:
class Article(models.Model):
code = models.CharField(max_length=20, blank=False, default='0216')
designation = models.CharField(max_length=200, blank=False)
unit = models.CharField(max_length=10, choices=choices_unite, default='')
quantity = models.FloatField(default=0)
quantity_in_stock = models.FloatField(default=0)
def __str__(self):
return self.designation
class ProductionArticle(models.Model):
article = models.ForeignKey(Article, on_delete=models.CASCADE)
planned quantity = models.FloatField(default=0)
production date = models.DateTimeField(default=timezone.now, verbose_name="Date d'ajout")
unit = models.CharField(max_length=10, choices=choices_unite, default='')
operator = models.CharField(max_length=200, default='Ahmed')
quantity_prod = models.FloatField(defaut=0)
哪个返回abstract class AbstractParent {
protected value: number;
constructor(value: number) {
this.value = value;
}
...
public times(multiplicator: number) {
return new ???(value * multiplicator);
}
}
的新Foo
和class Foo extends AbstractParent
的新Bar
?
答案 0 :(得分:1)
一种可维护的方法是将times
计算保留在基类中,并在create
和Foo
内实现单独的Bar
工厂方法。这样,基类不知道其扩展子类。
您在create
中将abstract
声明为AbstractParent
,以确保它将在所有子类中实现。 polymorphic this返回类型为times
的调用者确保返回的实例具有相同的子类类型(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
答案 1 :(得分:0)
您可以将子类型传递给父构造函数并保存引用。这样可以避免父母必须了解所有可能的孩子类型(尽管我同意另一个答案,即可能有更好的方法来实现您的总体目标)。像这样(playground link):
type ChildConstructor<Child> = new (value: number, childConstructor: ChildConstructor<Child>) => Child;
abstract class AbstractParent<Child extends AbstractParent<Child>> {
protected value: number;
protected childConstructor: ChildConstructor<Child>;
constructor(value: number, childConstructor: ChildConstructor<Child>) {
this.value = value;
this.childConstructor = childConstructor;
}
public times(multiplicator: number): Child {
return new this.childConstructor(this.value * multiplicator, this.childConstructor);
}
}
class Foo extends AbstractParent<Foo> {
constructor(value: number) {
super(value, Foo);
}
}
class Bar extends AbstractParent<Bar> {
constructor(value: number) {
super(value, Bar);
}
}
请注意,要获得100%的类型安全性,每个子类都需要至少具有一个附加的私有属性或方法,以使TypeScript的“鸭子类型”不被视为可互换类(因为它们共享相同的属性和方法) )。