interface CrudRepo {
fun save()
fun saveAll()
}
interface CustomRepo : CrudRepo {
fun validate()
override fun save() {
validate()
saveAll() // can call saveAll, I need to call save on CrudRepo here
}
}
Run Code Online (Sandbox Code Playgroud)
CrudRepo有一个不做验证的功能保存。我决定编写自己的接口来扩展CrudRepo和覆盖 save 方法。在我自己的定义,save我想验证,然后调用save的方法CrudRepo。
我应该尝试什么?
如果您尝试使用super,您将收到一条错误消息“无法直接访问抽象成员”。这适用于接口和类;你不能在 上调用无体抽象方法super。这意味着这不能编译:
interface CrudRepo {
fun save()
fun saveAll()
}
interface CustomRepo : CrudRepo {
fun validate()
override fun save() {
validate()
super.saveAll()
}
}
Run Code Online (Sandbox Code Playgroud)
但将 CrudRepo 接口更改为:
interface CrudRepo {
fun save()
fun saveAll(){
}
}
Run Code Online (Sandbox Code Playgroud)
确实如此。
如果你想要一个抽象的例子,这里是:
abstract class CrudRepo {
abstract fun save()
abstract fun saveAll()
}
class CustomRepo : CrudRepo() {
override fun saveAll() { }
override fun save() {
super.saveAll()
}
}
Run Code Online (Sandbox Code Playgroud)
您将收到相同的错误消息。这是因为您无法调用方法的未实现版本。另外,让我们看一下继承。
interface CustomRepo : CrudRepo
class MyClass : CustomRepo
Run Code Online (Sandbox Code Playgroud)
meansMyClass是 CrudRepo 和 CustomRepo 的子项。和MyClass() as CustomRepo都会MyClass() as CrudRepo编译。
现在,这对您的问题意味着什么?
从的角度来看,没有任何save方法。它尚未实现,因此您无法直接调用它。正如我上面所示的调用方式。是一个非常严格的关键字。但是,并没有被覆盖。可以调用,但是不能在超级接口上调用,因为超级接口没有带body的save方法CrudRepoCustomReposuper.saveAll()call the saveAll method on my parentsupersaveAll()savesave 方法。这句话的最后三个词在这里非常重要;由于 CrudBody 接口中定义的方法没有主体,因此您无法调用它。
此外,由于您已经重写了该方法,因此对它的任何调用都会导致递归。如果你这样做:
override fun save(){
save()
}
Run Code Online (Sandbox Code Playgroud)
它会一遍又一遍地调用自己,直到崩溃。请参阅什么是 StackOverflowError?。
现在,如果你有一个实际的课程:
class CustomRepoImpl : CustomRepo{
override fun saveAll() {
}
override fun save() {
super.save()
}
override fun validate() {
}
}
Run Code Online (Sandbox Code Playgroud)
注意它是如何调用的super;它现在将调用 中的 super 方法CustomRepo。然而,这并不是必须的。
当您重写savein时CustomRepo,请记住一件事:您正在重写 CrudRepo 的方法。任何子类都不再需要重写它。我的示例实现无需它即可编译。有效的原因saveAll(没有super关键字)是因为它是抽象的,并且不引用调用它的方法。请参阅 StackOverflowError 链接。如果调用重写的方法,则将调用子类中的方法,除非在 上调用该方法super。
而且您不能super在超类或接口中调用无主体方法,因为该语言不知道您指向什么,因为那里什么也没有。
TL;DR:您不能调用抽象/无体方法的超级方法。saveAll指该方法的第一个实现,或者如果在子类中定义则指超类。调用save将导致 StackOverflowError。
| 归档时间: |
|
| 查看次数: |
1956 次 |
| 最近记录: |