想象一下我们有一堂课:
class A {
public void m() {
System.out.println("A - > m()");
}
}...and,我想重写类创建上的方法m,而不使用生成第二个子类B来扩展A。
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()的私有方法。
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(),以及是否有其他方法来执行这个任务。
发布于 2015-01-26 11:31:55
我想知道为什么我不能写
A.super.m().
这是因为A实际上不是一个直接封闭的类。Runnable的直接封装类是new A() { ... },它是A的一个匿名子类。
换句话说,如果你
class A extends Base {
new Runnable() { ... }
}那么A.super会起作用的,但现在你已经
class <Anonymous subclass of A> extends A {
new Runnable() { ... }
}这意味着像A.super这样的东西是不可能的,因为<Anonymous subclass of A>.super.m没有语法。
...and,还有其他方法来执行这个任务吗?
在我看来,你解决这个问题的方式是合理的。另一种方法是创建A的本地子类(只需引入要在____.super.m中使用的标识符)如下:
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();
}发布于 2015-01-26 10:37:32
编写A.super.m(),假设A有一个带有m方法的超类。但是在您的代码中,您没有指定超类,默认情况下,您拥有的唯一超类是Object。
但是Object类没有'm‘方法,所以不能调用它。这样做的一个好方法是使用设计模式,比如装饰师。
发布于 2015-01-26 11:01:05
我认为除了你已经拥有的方式之外,没有其他更简单的方法了。
问题是匿名类A本身(不是基类A)不能在Runnable类中引用。在编译到自己的类文件时,匿名类被表示为类似于package.A$1的内容。例如,当在线程的superMethod中调用run时,将执行以下字节码:
getfield mypackage/Test$1$1/this$1 Lmypackage/Test$1;
invokestatic mypackage/Test$1/access$0(Lmypackage/Test$1;)V为了引用它的基类A,没有对这个内部类实例的引用,所以您可以调用super.m()表达式。
https://stackoverflow.com/questions/28148424
复制相似问题