Typescript:Access祖父母类方法

Typescript:Access祖父母类方法,typescript,Typescript,我有一个三班的家庭: 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 submi

我有一个三班的家庭:

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;
    }
}
抽象类形式{
受保护的异步提交({url:string,data:any}):承诺{
//从表单提交数据
}
}
抽象类BookForm扩展了表单{
公共名称?:字符串;
公共抽象异步提交():承诺
}
类UpdateBookForm扩展了BookForm{
私有id:string;
公共异步提交():承诺{
//无法通过超级表达式访问类“BookForm”中的抽象方法“submit”。
返回super.submit({
url:“/book/update”,
数据:{
id:this.id,
姓名:this.name,
}
});
}
构造函数(bookId:string){
超级()
this.id=bookId;
}
}
尝试从
UpdateBookForm
访问
super.submit()
方法时出错

无法通过超级表达式访问类“BookForm”中的抽象方法“submit”

我试图实现的是
BookForm
知道它的派生函数包含方法
submit()
,而在
BookForm
中没有任何实现


关于如何做到这一点有什么建议吗?也许我可以从
UpdateBookForm

中直接访问祖父母(
super.super
?),从
BookForm
中删除
abstract
方法,使其:

abstract class BookForm extends Form {
    public name?: string;
}
仅仅制作
书单
摘要
就足以防止它被使用

您永远不希望用不存在的方法(在
BookForm
中)覆盖(在
Form
中)存在的方法

在一篇评论中,您概述了制作
submit
abstract
的动机,并说(为了匹配问题,我将下面的“
save
”改为“
submit
”):


好吧,假设我有一个
BookForm
的实例,比如
constbookform=this.book?新建UpdateBookForm(this.book):新建CreateBookForm()
,我尝试保存它
bookForm.submit()
它需要
Form
中的
submit
方法,该方法需要参数。我想调用
bookForm.submit()

如果
BookForm
UpdateBookForm
没有接受参数的
submit
,那么它们违反了子类实例“是”超类实例的规则,因为它们不是
Form
s。有多种方法可以解决这个问题。一种是让
提交
受保护
并让
书单
添加
摘要
保存
或其他内容。然后,
UpdateBookForm
CreateBookForm
将通过调用
submit
来实现
save

但我也会仔细检查继承是否是正确的选择。没有更多的上下文很难说



旁注:
BookForm
可能应该有一个初始化
name
的构造函数。引入一个字段,而不需要在层次结构的同一级别上初始化它。

您可以直接调用祖辈类名称,尽管您可能会考虑重新设计代码。它有一种密码的味道

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,
            }
        });
    }
}
抽象类形式{
异步提交({url:string,data:any}):承诺{
//从表单提交数据
}
}
抽象类BookForm扩展了表单{
公共名称?:字符串;
抽象异步提交():承诺
}
类UpdateBookForm扩展了BookForm{
私有id:string;
异步提交():承诺{
返回表单。原型。提交。调用(此{
url:“/book/update”,
数据:{
id:this.id,
姓名:this.name,
}
});
}
}

多亏了T.J.Crowder的回答,我得出结论,
表单
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;
    }
}
抽象类形式{
受保护的异步提交({url:string,data:any}):承诺{
//从表单提交数据
}
公共抽象异步保存():承诺
}
抽象类BookForm扩展了表单{
公共名称?:字符串;
公共抽象异步保存():承诺
}
类UpdateBookForm扩展了BookForm{
私有id:string;
公共异步保存():承诺{
返回super.submit({
url:“/book/update”,
数据:{
id:this.id,
姓名:this.name,
}
});
}
构造函数(bookId:string){
超级()
this.id=bookId;
}
}

很有趣。我正在评估一些不同的策略,虽然不在主题范围内,但如果您能详细说明代码,这对我来说将是非常有价值的。@nomadoda我真的无法用语言表达出来,但在派生类中有一个从非抽象到抽象的方法似乎很奇怪。我想不出有什么方法会导致运行时错误,但对我来说这似乎很奇怪,仅此而已。也就是说,上面的代码应该是有效的,你有枪来解决你的问题,只是小心别开枪:POk,好吧,假设我有一个
BookForm
的实例,比如
const BookForm=this.book?新建UpdateBookForm(this.book):新建CreateBookForm()
,我尝试保存它
bookForm.save()
它需要
Form
中的save方法,该方法需要参数。我想调用
bookForm.save()
@nomadoda-By
save
我猜您的意思是
submit
(您问题中使用的名称)。如果
BookForm
UpdateBookForm
没有接受参数的
submit
,那么它们违反了子类实例“是”超类实例的规则,因为它们不是
Form
s。有各种各样的