Reputation: 408
NOTE:
I am aware that this is dangerously close to many other questions. I haven't seen any, however, that do not pertain specifically to Android's OnClickListener interface. I am asking in a general sense.
I understand the difference between instantiating an interface via an anonymous class... a la:
private final Runnable runnable = new Runnable() {
@Override
public void run() {
draw();
}
};
... and extending the interface.
public class ClassyClass implements Runnable {
...
//do other cool stuff here
...
@Override
public void run() {
draw();
}
...
//and more here
...
}
But, other than the obvious benefits from interfaces such as OnClickListener
is there a strong advantage to either option?
I would think that extending it would be the obvious choice because you are already creating that object - no duplication of effort. Is this right?
I am asking in a general sense but, as I am currently working with Runnable
, if it has sees an advantage from either option I'd love to know.
Upvotes: 1
Views: 471
Reputation: 613
Both approaches are valid. Which one to use depends of your usage:
Upvotes: 0
Reputation: 37845
Well here is an example that shows the main differences. It's a little contrived but it's just to illustrate.
Here is an anonymous version:
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;
}
}
Here is a nested version:
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);
}
}
}
So you can see the main differences are then:
In particular, in the above example, the PrintBuilder is leaked until the inner Runnable objects die. In the second example, the Runnable class is static so it doesn't have this problem.
An anonymous class doesn't need fields and constructors because they are implicit.
An anonymous class is declared where it's instantiated and this can be pretty destructive to the layout of the enclosing class if the anonymous class isn't very short. On the other hand if the anonymous class is short, the functional-like syntax is nice.
Also all classes tend to grow and in my experience this can turn in to a smell when an anonymous class gets too big. Anonymous classes are also much more difficult to refactor in to a top-level class.
Upvotes: 2
Reputation: 691685
The first snippet defines a class, without a name, that implements the Runnable interface (and instantiates that anonymous class). The second one defines a class, with a name, that also implements the Runnable interface.
There's no difference in terms of inheritance and interface implementation except the second class has a name and the first one doesn't.
The second snippet allows multiple classes to instantiate the Runnable implementation, whereas the first one defines a class that is only known from its enclosing class. Sometimes one is better, sometimes the other.
Upvotes: 0