注意:
我知道这与许多其他问题非常接近。然而,我还没有看到任何与 Android 的 OnClickListener 接口(interface)无关的内容。我问的是一般意义上的。
我理解通过匿名类实例化接口(interface)之间的区别...... 啦:
private final Runnable runnable = new Runnable() {
@Override
public void run() {
draw();
}
};
...并扩展接口(interface)。
public class ClassyClass implements Runnable {
...
//do other cool stuff here
...
@Override
public void run() {
draw();
}
...
//and more here
...
}
但是,除了 OnClickListener
等接口(interface)的明显好处之外,这两个选项还有什么强大的优势吗?
我认为扩展它是显而易见的选择,因为您已经在创建该对象 - 无需重复工作。这是正确的吗?
我问的是一般意义上的问题,但是,由于我目前正在使用Runnable
,我很想知道它是否从这两个选项中看到了优势。
最佳答案
这是一个显示主要差异的示例。虽然有点做作,但只是为了说明。
这是一个匿名版本:
class PrintBuilder {
List<Runnable> printers = new LinkedList<>();
List<Runnable> get() {
return printers;
}
PrintBuilder add(final String line) {
printers.add(new Runnable() {
public void run() {
System.out.println(line);
}
});
return this;
}
}
这是一个嵌套版本:
class PrintBuilder {
List<Printer> printers = new LinkedList<>();
PrintBuilder add(String line) {
printers.add(new Printer(line));
return this;
}
List<Printer> get() {
return printers;
}
static class Printer implements Runnable {
String line;
Printer(String line) {
this.line = line;
}
public void run() {
System.out.println(line);
}
}
}
所以你可以看到主要的区别是:
- 匿名类是内部类,它具有对封闭实例的隐式引用。
特别是,在上面的示例中,PrintBuilder 会泄漏,直到内部 Runnable 对象死亡为止。在第二个示例中,Runnable 类是静态的,因此不存在此问题。
- 匿名类稍微短一些。
匿名类不需要字段和构造函数,因为它们是隐式的。
- 代码的组织方式存在巨大差异。
匿名类是在实例化的地方声明的,如果匿名类不是很短,这可能会对封闭类的布局造成很大的破坏。另一方面,如果匿名类很短,那么类似函数的语法就很好。
此外,所有类都会增长,根据我的经验,当匿名类变得太大时,这可能会变成一种气味。匿名类也更难以重构为顶级类。
关于java - 扩展接口(interface)与通过匿名类实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22728932/