考虑以下课程:
public abstract class AbstractClass {
public abstract String m();
public AbstractClass get(){
return new AbstractClass() {
@Override
public String m() {
return "Anonymous " + super.m(); //1, Compile-time erro
}
};
}
}
目前尚不清楚为何禁止使用super
。在//1
,发生以下错误
Cannot directly invoke the abstract method m() for the type AbstractClass
所以,我咨询了JLS 15.11.2并没有找到阻止这些代码编译的限制。他们在这里:
如果使用关键字super的表单出现,则是编译时错误 在Object类的声明中,因为Object没有超类。
AbstractClass
的实例不可能,但只有一个 具体的 子类,以下内容对我来说也是有效的:使用关键字super的表单仅在实例中有效 方法,实例初始值设定项或构造函数,或者在初始化程序中 类的实例变量。如果他们出现在其他任何地方, 发生编译时错误。
如果当前类不是内部类,则是编译时错误 T或T本身。
当然,我可以使用AbstractClass.this.m()
,但这不是我要问的。
答案 0 :(得分:16)
super关键字在这里不起作用,因为AbstractClass.m()
已被声明为abstract,因此在内部类的父级上没有合适的实现。请记住,内部类不扩展外部类(即使它是相同的类型),它们包含对它的引用。
但是当从内部类调用到外部类(这是我认为你打算在这里做的)时,请使用以下语法AbstractClass.this.m()
。
以下内容将按预期编译和工作。
public abstract class AbstractClass {
public abstract String m();
public AbstractClass get(){
return new AbstractClass() {
@Override
public String m() {
return "Anonymous " + AbstractClass.this.m();
}
};
}
}
答案 1 :(得分:6)
据我所知,编译器在使用super.m();
时尝试使用静态绑定。由于没有方法super.m();
,因为它是抽象的,编译器已经在编译时抱怨。
Java中的静态绑定意味着在编译期间解析方法,而在运行时使用可被多个子类覆盖的方法时发生动态绑定。