Anonymous Inner Class request for clarification
While learning TTS on Android, I came across the following code snippet:
speakB开发者_如何学Ctn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
mTts.speak(words.getText().toString(), TextToSpeech.QUEUE_ADD, null);
}});
I am really new to Java, so my level of confidence in identifying the various constructs isn't that great. I think that I see above is an Anonymous Inner Class but the 'new OnClickListener()' is confusing to me. So please confirm and/or correct any of the following understanding:
- The inner class is defined right after new OnClickListener().
- OnClickListener is a super class from which the inner class is derived.
- The (anonymous) inner class has only one member function: OnClick().
- What is @Override inside the definition of the inner class? If this is an annotation, then I am confused as this answer states that anonymous inner classes cannot be annotated.
Lastly, is there a way to write the above snippet in a way that is easier to decipher for a n00b like me?
- Yes; it's defined between the braces.
- Yes, except that it's an interface, not a class.
- Yes.
- You cannot add class-level annotations.
@Override
is a method-level annotation, which works fine.
Well, basically this snippet of code creates a class which name is mangled by the compiler for your convinience so that you need'nt care about naming it yourself. That class will implement the interface OnClickListener, and contain implementation for the method onClick(View), as the interface requires.
As such, your snippet could be writter some way like this:
class OnClickListenerThingy01 implements OnClickListener { // name is invented from the top of my head and corresponds actual name manging in no way
@Override
public void onClick(View view) {
mTts.speak(words.getText().toString(), TextToSpeech.QUEUE_ADD, null);
}
}
speakBtn.setOnClickListener(new OnClickListenerThingy01());
The @Override annotation is not placed on the class itself - which has no declaration in your code the annotation could be added, being compiler-generated - but on the method.
The @Override annotation is used to mark overrides (how surprising) and method implementations. Its main use is to generate a compiler error if the signature of the overridden method changes, but you fail to update the overriding declaration accordingly, so that you won't get really surprised when you overrides fail to work, because, say, what was overridden was renamed.
In case on an interface implementation, if you forget to implement an interface fully, the compiler will generate an error anyways, so @Override may seem a bit redundant, but it is not. In fact, it is a rather nice thing to have so that unneccessary methods (when for example, a method declaration is removed from an interface) won't stay in your code.
Although it must be noted that an IDE like Eclipse will most probably make these concerns void, as the provided refactoring tools are more than enough to avoid such situtation. Anyways, @Override is quite nice to have on you methods when it may be used.
Here's a way to rewrite your snippet that makes it much clearer "to a noob" :)
class MyOuterClass {
private class MyOnClickListener implements OnClickListener {
@Override
public void onClick(View view) {
mTts.speak(words.getText().toString(), TextToSpeech.QUEUE_ADD, null);
}
}
// later (inside some method)...
speakBtn.setOnClickListener(new MyOnClickListener());
}
- The inner class is defined right after new OnClickListener().
Think of the code there as describing an unnamed subclass of OnClickListener(). The class definition is within the brackets, just as you thought.
- OnClickListener is a super class from which the inner class is derived.
Yes
- The (anonymous) inner class has only one member function: OnClick().
It does, but that does not have to be the case. It could have more member functions.
- What is @Override inside the definition of the inner class? If this is an annotation, then I am confused as this answer states that anonymous inner classes cannot be annotated.
@Override is used for compile-time error-checking on methods. You can use method-level annotations on an anonymous inner class.
OnClickListener is a super class from which the inner class is derived
Not really : OnClickListener is not a class. This syntaxis is used to create an instance of a new (anonymous) class which implements the interface OnClickListener. So you have only one method to implement : onClick().
精彩评论