NOTE:
我知道这很危险地接近许多其他问题。但是,我还没有看到任何与Android的OnClickListener界面无关的内容。我是一般意义上的问题。
我理解通过匿名类实例化接口之间的区别...... la:
private final Runnable runnable = new Runnable() {
@Override
public void run() {
draw();
}
};
...并扩展界面。
public class ClassyClass implements Runnable {
...
//do other cool stuff here
...
@Override
public void run() {
draw();
}
...
//and more here
...
}
但是,除了OnClickListener
这样的接口带来的明显好处之外,这两种选择都有很大的优势吗?
我认为扩展它将是显而易见的选择,因为你已经在创造那个对象 - 没有重复的努力。这是对的吗?
我在一般意义上问,但是,正如我目前正在与Runnable
合作,如果它看到任何一种选择的优势,我很乐意知道。
答案 0 :(得分:2)
这里有一个显示主要差异的例子。它有点做作,但只是为了说明。
这是一个匿名版本:
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类是静态的,因此它不会出现此问题。
匿名类不需要字段和构造函数,因为它们是隐式的。
匿名类在它被实例化的地方被声明,如果匿名类不是很短,这对封闭类的布局非常具有破坏性。另一方面,如果匿名类很短,那么类似函数的语法就很好了。
此外,所有课程都会增长,根据我的经验,当匿名课程变得太大时,这可能会变成一种气味。匿名类也很难重构到顶级类。
答案 1 :(得分:0)
第一个片段定义了一个没有名称的类,它实现了Runnable接口(并实例化了该匿名类)。第二个定义了一个带有名称的类,它也实现了Runnable接口。
继承和接口实现方面没有区别,除了第二个类有名称而第一个类没有。
第二个片段允许多个类实例化Runnable实现,而第一个片段定义一个只能从其封闭类中获知的类。有时一个更好,有时另一个。
答案 2 :(得分:0)
两种方法都有效。使用哪一个取决于您的用法: