我有一个三班制的家庭:
abstract class Form {
protected async submit({ url: string, data: any }): Promise<void> {
// submit data from form
}
}
abstract class BookForm extends Form {
public name?: string;
public abstract async submit(): Promise<void>
}
class UpdateBookForm extends BookForm {
private id: string;
public async submit(): Promise<void> {
// Abstract method 'submit' in class 'BookForm' cannot be accessed via super expression.
return super.submit({
url: '/book/update',
data: {
id: this.id,
name: this.name,
}
});
}
constructor(bookId: string) {
super()
this.id = bookId;
}
}
尝试从super.submit()
访问UpdateBookForm
方法时遇到错误。
无法通过超级表达式访问“ BookForm”类中的抽象方法“ submit”。
我要实现的目标是BookForm
知道其包含方法submit()
的派生类,而在BookForm
中没有任何实现。
关于如何实现此目标的任何建议?也许我可以直接从super.super
访问祖父母(UpdateBookForm
?)?
答案 0 :(得分:2)
从abstract
删除BookForm
方法,使其:
abstract class BookForm extends Form {
public name?: string;
}
仅仅制作BookForm
abstract
就足以防止它被使用。
您永远不想用不存在的方法(在Form
中覆盖现有的方法(在BookForm
中)。
在评论中,您概述了制作submit
abstract
的动机,方法是(我在下面将“ save
”更改为“ submit
”,匹配问题):
好吧,好吧,我在
BookForm
中有一个const bookForm = this.book ? new UpdateBookForm(this.book) : new CreateBookForm()
的实例,我尝试保存它bookForm.submit()
,它期望从submit
使用Form
方法需要参数。我想打bookForm.submit()
。
如果BookForm
和UpdateBookForm
没有有意义的submit
接受参数,则它们违反了子类实例“是”超类实例的规则,因为它们不是Form
个。有多种解决方法。一种方法是制作submit
protected
并让BookForm
添加abstract
save
之类的东西。然后UpdateBookForm
和CreateBookForm
将通过调用save
来实现submit
。
但是我还要仔细检查继承在这里是否正确。没有更多的上下文很难说。
旁注:BookForm
应该有一个初始化name
的构造函数。引入字段而无需在层次结构的相同级别上对其进行初始化的方法似乎是不可能的。
答案 1 :(得分:0)
尽管您可能会考虑重新设计代码,但是您可以直接使用祖父母类名称来调用它。
abstract class Form {
async submit({ url: string, data: any }): Promise<void> {
// submit data from form
}
}
abstract class BookForm extends Form {
public name?: string;
abstract async submit(): Promise<void>
}
class UpdateBookForm extends BookForm {
private id: string;
async submit(): Promise<void> {
return Form.prototype.submit.call(this, {
url: '/book/update',
data: {
id: this.id,
name: this.name,
}
});
}
}
答案 2 :(得分:0)
感谢T.J.根据Crowder的回答,我得出的结论是Form
submit({ url: string, data: any })
函数实际上与子类submit()
函数完全不同,因此将它们分成两个这样的函数是有意义的:
abstract class Form {
protected async submit({ url: string, data: any }): Promise<void> {
// submit data from form
}
public abstract async save(): Promise<void>
}
abstract class BookForm extends Form {
public name?: string;
public abstract async save(): Promise<void>
}
class UpdateBookForm extends BookForm {
private id: string;
public async save(): Promise<void> {
return super.submit({
url: '/book/update',
data: {
id: this.id,
name: this.name,
}
});
}
constructor(bookId: string) {
super()
this.id = bookId;
}
}