理解抽象类的超级关键字

时间:2015-10-08 09:45:17

标签: java super

考虑以下课程:

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并没有找到阻止这些代码编译的限制。他们在这里:

  1. 显然
  2.   

    如果使用关键字super的表单出现,则是编译时错误   在Object类的声明中,因为Object没有超类。

    1. 由于AbstractClass的实例不可能,但只有一个 具体的 子类,以下内容对我来说也是有效的:
    2.   

      使用关键字super的表单仅在实例中有效   方法,实例初始值设定项或构造函数,或者在初始化程序中   类的实例变量。如果他们出现在其他任何地方,   发生编译时错误。

      1. 不是这样。
      2.   

        如果当前类不是内部类,则是编译时错误   T或T本身。

        当然,我可以使用AbstractClass.this.m(),但这不是我要问的。

2 个答案:

答案 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中的静态绑定意味着在编译期间解析方法,而在运行时使用可被多个子类覆盖的方法时发生动态绑定。