Java 理解抽象类的超关键字

Java 理解抽象类的超关键字,java,super,Java,Super,考虑以下类别: public abstract class AbstractClass { public abstract String m(); public AbstractClass get(){ return new AbstractClass() { @Override public String m() { return "Anonymous " + super.m(

考虑以下类别:

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
因此,我查阅了数据库,没有发现阻止编译此类代码的限制。这是:

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

  • 由于不可能有一个
    AbstractClass
    的实例,但只能有一个具体的子类,因此在我看来,以下内容也是有效的:
  • 使用关键字super的表单仅在实例中有效 方法、实例初始值设定项或构造函数,或 类的实例变量。如果它们出现在其他任何地方 发生编译时错误

  • 事实并非如此
  • 如果当前类不是内部类,则为编译时错误 属于T类或T类本身


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

    据我所知,编译器在使用
    super.m()时尝试使用静态绑定。因为没有方法
    super.m()由于它是抽象的,编译器在编译时已经在抱怨了


    Java中的静态绑定意味着在编译时解析方法,而在运行时使用可由多个子类重写的方法时会发生动态绑定。

    super关键字在此处不起作用,因为
    AbstractClass.m()
    已声明为抽象,因此,在内部类的父级上没有合适的实现。请记住,内部类并不扩展外部类(即使它是同一类型),而是包含对它的引用

    但是,当从内部类调用外部类(我相信您在这里就是这么做的)时,请使用以下语法
    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(); 
                }
            };
        }
    
    }
    

    为什么要在这里调用
    super.m()
    ?该方法未在
    抽象类中实现,因此尝试调用它毫无意义。@Jesper是的,它不是。但正如我已经说过的,它是在conrete类中实现的。我们不能有
    AbstractClass
    本身的实例,只能有它的一个子类。请注意,
    super.m()
    不调用在匿名子类中重写的
    m
    。您告诉Java显式调用超类中的实现。由于该方法在超类中是抽象的,因此无法调用它。(您希望
    super.m()
    做什么?)如果您使用
    super
    调用一个方法,那么查找要调用的方法的正常多态性规则不适用。它将在超类中显式查找,并且不会在子类(JLS 15.12.1)中调用该方法的重写版本。@Jesper是的,现在我明白了,谢谢。如果表格是超级的。NonWildTypeArgumentsPt标识符,则方法的名称是标识符,要搜索的类是其声明包含方法调用的类的超类。旁注:如果保留get()返回的AbstractClass,不要忘记,它仍将保存对您调用get()所针对的原始抽象类的引用。如果您删除对原始对象的引用,并期望它获得GC'd。。。不会的。这是一个常见的问题,它会导致意外的内存泄漏。因此,如果表单是super,请注意。NonWildTypeArgumentsPT标识符,则方法的名称是标识符,要搜索的类是其声明包含方法调用的类的超类。在这里也是相关的,不是吗?@St.Antario是的。super关键字表示“扫描当前对象的对象层次结构以查找方法”。在您的示例中,有两个“AbstractClass”类型的对象,第三个对象是隐含的(但不包括在内),因此存在混淆。这三个是,1)抽象类本身,2)在get()中创建的匿名内部类,以及3)调用get()所需的抽象类的子类。内部类one直接扩展了AbstractClass,因此扫描其父类中的m()将发现没有实现的m()的抽象声明。