首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从重写方法内的匿名内部类中调用超级方法

从重写方法内的匿名内部类中调用超级方法
EN

Stack Overflow用户
提问于 2015-01-26 10:31:28
回答 3查看 6.8K关注 0票数 21

想象一下我们有一堂课:

代码语言:javascript
复制
class A {
  public void m() {
     System.out.println("A - > m()");
  }
}

...and,我想重写类创建上的方法m,而不使用生成第二个子类B来扩展A

代码语言:javascript
复制
public static void main(String[] args) {
    A a = new A() {
        @Override
        public void m() {
            System.out.println("Override - > m()");
            new Thread(new Runnable() {
                @Override
                public void run() {
                   // I want to be able to call the super method.
                   // This is illegal!
                   A.super.m();
                }
            }).start();
        }
    };
    a.m();
}

目前,我的解决方案是创建一个调用super.m()的私有方法。

代码语言:javascript
复制
   A a = new A() {

        private void superMethod() {
            super.m();
        }

        @Override
        public void m() {
            System.out.println("Overrided - > m()");
            new Thread(new Runnable() {

                @Override
                public void run() {
                    superMethod();
                }
            }).start();
        }
    };
    a.m();

我想知道为什么我不能编写A.super.m(),以及是否有其他方法来执行这个任务。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-01-26 11:31:55

我想知道为什么我不能写A.super.m().

这是因为A实际上不是一个直接封闭的类。Runnable的直接封装类是new A() { ... },它是A的一个匿名子类。

换句话说,如果你

代码语言:javascript
复制
class A extends Base {
    new Runnable() { ... }
}

那么A.super会起作用的,但现在你已经

代码语言:javascript
复制
class <Anonymous subclass of A> extends A {
    new Runnable() { ... }
}

这意味着像A.super这样的东西是不可能的,因为<Anonymous subclass of A>.super.m没有语法。

...and,还有其他方法来执行这个任务吗?

在我看来,你解决这个问题的方式是合理的。另一种方法是创建A的本地子类(只需引入要在____.super.m中使用的标识符)如下:

代码语言:javascript
复制
public static void main(String[] args) {

    class SubA extends A {
        @Override
        public void m() {
            System.out.println("Override - > m()");
            new Thread(new Runnable() {

                @Override
                public void run() {
                    SubA.super.m();
                 // ^^^^ we now have a name of the directly enclosing class
                }
            }).start();
        }
    }
    A a = new SubA();
    a.m();
}
票数 13
EN

Stack Overflow用户

发布于 2015-01-26 10:37:32

编写A.super.m(),假设A有一个带有m方法的超类。但是在您的代码中,您没有指定超类,默认情况下,您拥有的唯一超类是Object。

但是Object类没有'm‘方法,所以不能调用它。这样做的一个好方法是使用设计模式,比如装饰师。

票数 4
EN

Stack Overflow用户

发布于 2015-01-26 11:01:05

我认为除了你已经拥有的方式之外,没有其他更简单的方法了。

问题是匿名类A本身(不是基类A)不能在Runnable类中引用。在编译到自己的类文件时,匿名类被表示为类似于package.A$1的内容。例如,当在线程的superMethod中调用run时,将执行以下字节码:

代码语言:javascript
复制
getfield mypackage/Test$1$1/this$1 Lmypackage/Test$1;
invokestatic mypackage/Test$1/access$0(Lmypackage/Test$1;)V

为了引用它的基类A,没有对这个内部类实例的引用,所以您可以调用super.m()表达式。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28148424

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档