View.setOnClickListener( new View.OnClickListener(){
#override
public void onClick(View view){
//Some code implementing this method
}
});
Here OnClickListener is a static Interface declared inside View. Since it is static, it won't be categorized as an Inner class (correct me if I'm wrong here).
Then how can we use an anonymous class to inline implement this static nested interface?
Since, as I know they are only used to inline implement inner classes which are nested types without the static keyword for enclosed type.
First of all: inner interfaces are "static" by default. It is not possible to have an "inner" interface that wouldn't be static! See here for some more thoughts on that aspect.
From that point of view, interfaces are just that: interfaces. Doesn't matter if they are a top level interface sitting in their own .java file, or if the interface sits within some class or so.
And any interface can be implemented using an anonymous inner class.
That is really all there is to this.
To answer to the comment:
so the inline implementation ie the anonymous class itself becomes an inner class of the interface it implements?
No, an anonymous inner class is an inner class of the class that wraps around it. It happens to implement some interface. It is not an inner class of the interface. Inner is really meant in a "physical" sense, as in lines of code sitting inside other blocks of code.
class Outer {
class/interface Inner {
Inner is called an inner class/interface because it lives inside Outer.
Related
I am making a series of files to teach students interfaces, and each one will have an interface called Recycle in it. However, when I get to the second file, Eclipse gives me an error saying Recycle has already been defined. Here is roughly what my code looks like:
public class Example101
{
//methods here
}
interface Recycle
{
//abstract methods here
}
I'd really like to keep the interfaces in the same files as the example classes.
You can define types inside other types, using them as mini packages contained within one file:
public class Example101 {
interface Recycle {}
static class X implements Recycle {}
}
One thing you can't do is have the outer class Example101 itself implement an interface declared inside it. So to implement the interface you'll probably want another class declared inside Example101 too.
Member classes like X should be declared static, unless you want them bound to a created instance of the outer class Example101. To also declare the Recycle interface static is valid but redundant; member interfaces are always static (JLS §8.5.1). Alternatively, if you make the outer type Example101 an interface, all its member types are implicitly static (JLS §9.5).
Create packages.
Create the interfaces in the packages.
What's the difference between using interface inside class, inside nested class and outside class.
As I was reading about the class DataStructure.java in Questions and Exercises: Nested Classes at Oracle (pasting here fragment of the example):
public class DataStructure {
//some code
interface DataStructureIterator extends java.util.Iterator<Integer> { }
// Inner class implements the DataStructureIterator interface,
// which extends the Iterator<Integer> interface
private class EvenIterator implements DataStructureIterator {
//rest code
So as the code about shows there is no any body in interface. Couldn't I just extends EvenIterator class with java.util.Iterator<Integer> instead of creating this interface and implements it?
Is there any other difference (aside from code readability) between declaring interference outside/inside class?
What will happen when the outer class gonna be extended by a interface. Will it impact in any way on nested class?
Just want to be sure about these things to know how to use them properly, thanks for your time.
So as the code about shows there is no any body in interface. Couldn't I just extends EvenIterator class with
java.util.Iterator instead of creating this interface and
implements it?
Yes, you could. But this way it may be more readable and extendable. Even if there are no members now, they may be added later.
Is there any other difference (aside from code readability) between declaring interference outside/inside class?
A nested interface is implicitly static, so the only effect is that a nested interface is a part of the enclosing class namespace-wise.
Because members of a class may be declared as protected or private, that applies to nested interfaces as well. It rarely makes sense to use private interfaces, though, because they can only be implemented in the same class, so why bother with interfaces in the first place? However, protected interfaces may be useful. For example, you may have an abstract factory method that is used by the subclasses to provide instances to the parent class. Here's a contrived example:
public abstract class Enclosing {
protected interface JobHandler {
void handle(Job job) throws JobException;
}
protected abstract JobHandler createJobHandler();
// public methods omitted
private void doTheJob(Job job) {
createJobHandler().handle(job);
}
}
If the interface is declared package-private, it might as well just be at the package level. The only reason you may want to cram it inside a class is because it's very tightly coupled to the class itself. Perhaps it's some sort of helper interface that is used strictly in unit testing that particular class.
If the interface is public, then it's usually a bad idea to make it nested. Because by doing that, you increase coupling between the interface and the enclosing class. And interfaces are one of the best ways to reduce coupling! So why waste their potential?
Suppose you have a mylib-buttons library that have a Button class. One day having a Button.ClickListener seems to be a nice idea. Then you want to reuse this interface in another class, and possibly even in another library. But you can't do it without introducing a (probably unnecessary) dependency on the library that contains the Button class. On the other hand, if it's a top-level interface, then you just extract the interfaces into another library, say, mylib-core, leaving the messy buttons alone in the mylib-buttons.
Nested interfaces inside interfaces is a bit different story. They can be a part of the same design and intended to be used together. #cricket_007 in one of the comments gives a good example of that: Map.Entry.
What will happen when the outer class gonna be extended by a interface. Will it impact in any way on nested class?
This is not exactly clear. How can a class be extended by an interface? Nevertheless, whatever you meant here, you can probably answer it yourself if you consider the aforementioned fact: the nested interface is just a part of the class' namespace scope, and that's it. There are no other impacts whatsoever.
I am making changes to a Java class of ours, and I noticed the following line of code:
OurClass<OurInterface1> ourClass = new OurClass<OurInterface1>() {};
What I find strange about that line is that OurClass is an abstract class - here's the definition of OurClass:
public abstract class OurClass<T extends OurInterface1> implements OurInterface2<T>
When I remove the {} at the end of the line, Eclipse tells me Cannot instantiate the type OurClass<OurInterface1>, but when I put the {} back, everything is OK.
How does {} allow you to instantiate an abstract class?
Adding the {} introduces the syntax for an anonymous inner class.
The anonymous class expression consists of the following:
The new operator
The name of an interface to implement or a class to extend. In this example, the anonymous class is implementing the interface HelloWorld.
Parentheses that contain the arguments to a constructor, just like a normal class instance creation expression. Note: When you implement an interface, there is no constructor, so you use an empty pair of parentheses, as in this example.
A body, which is a class declaration body. More specifically, in the body, method declarations are allowed but statements are not.
You are declaring an anonymous inner class that subclasses OurClass. The body of this class is empty: {}. This anonymous inner class is not abstract, so you are able to instantiate it.
When you remove the {}, the compiler thinks that you are directly instantiating OurClass, an abstract class, so it disallows it.
You can actually extend and override methods on the fly when you instantiate off an interface or extendible class. This is called an anonymous inner class.
What you did in your example is create an anonymous inner class, but it had no effect because you didn't override anything. You could have put overridden methods in those curly brackets {}.
OurClass<OurInterface1> ourClass = new OurClass<OurInterface1>() {};
A commonly applied use of anonymous inner class is on the Runnable interface, which defines a single void run() method. You can implicitly instantiate an object that implements Runnable and override run() on the fly.
Runnable someTask = new Runnable() {
#Override
public void run() {
System.out.println("Running a task!");
}
};
Anonymous inner classes are disliked by a lot of developers because they are pretty verbose. Fortunately in Java 8, you can use lambda expressions to replace most anonymous inner classes that implement a single method. The compiler infers the anonymous inner class for you basically, allowing you to write the code more concisely.
Runnable someTask = () -> System.out.println("Running a task!");
The block after the call to the new operator (new OurClass<OurInterface1>() {}) is infact creating an instance of an anonymous class which extends OutClass.
Since this class is no longer abstract, there's no problem to instantiate it.
You cannot instantiate an abstract class without implementing the abstract functions within the class. This is usually done by instatiating abstract classes with implemented class.
Refer: https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
In your case, the {} used after the instantiation allows you to implement any of the abstract functions in the abstract class.
For example,
Consider
public abstract class DummyClass {
abstract void test() ;
}
is the abstract class with a abstract function.
The class can be initiated by:
DummyClass d = new DummyClass(){
void test(){
//test() implementation here
}
} ;
Hope this helps! :)
While learning TTS on Android, I came across the following code snippet:
speakBtn.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().
I observed that Outer classes can access inner classes private instance variables. How is this possible? Here is a sample code demonstrating the same:
class ABC{
class XYZ{
private int x=10;
}
public static void main(String... args){
ABC.XYZ xx = new ABC().new XYZ();
System.out.println("Hello :: "+xx.x); ///Why is this allowed??
}
}
Why is this behavior allowed?
The inner class is just a way to cleanly separate some functionality that really belongs to the original outer class. They are intended to be used when you have 2 requirements:
Some piece of functionality in your outer class would be most clear if it was implemented in a separate class.
Even though it's in a separate class, the functionality is very closely tied to way that the outer class works.
Given these requirements, inner classes have full access to their outer class. Since they're basically a member of the outer class, it makes sense that they have access to methods and attributes of the outer class -- including privates.
If you like to hide the private members of your inner class, you may define an Interface with the public members and create an anonymous inner class that implements this interface. Example bellow:
class ABC{
private interface MyInterface{
void printInt();
}
private static MyInterface mMember = new MyInterface(){
private int x=10;
public void printInt(){
System.out.println(String.valueOf(x));
}
};
public static void main(String... args){
System.out.println("Hello :: "+mMember.x); ///not allowed
mMember.printInt(); // allowed
}
}
The inner class is (for purposes of access control) considered to be part of the containing class. This means full access to all privates.
The way this is implemented is using synthetic package-protected methods: The inner class will be compiled to a separate class in the same package (ABC$XYZ). The JVM does not support this level of isolation directly, so that at the bytecode-level ABC$XYZ will have package-protected methods that the outer class uses to get to the private methods/fields.
There's a correct answer appearing on another question similar to this:
Why can the private member of an nested class be accessed by the methods of the enclosing class?
It says there's a definition of private scoping on JLS - Determining Accessibility:
Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
Thilo added a good answer for your first question "How is this possible?". I wish to elaborate a bit on the second asked question: Why is this behavior allowed?
For starters, let's just be perfectly clear that this behavior is not limited to inner classes, which by definition are non-static nested types. This behavior is allowed for all nested types, including nested enums and interfaces which must be static and cannot have an enclosing instance. Basically, the model is a simplification down to the following statement: Nested code have full access to enclosing code - and vice versa.
So, why then? I think an example illustrate the point better.
Think of your body and your brain. If you inject heroin into your arm, your brain gets high. If the amygdala region of your brain see what he believe is a threat to your personally safety, say a wasp for example, he'll make your body turn the other way around and run for the hills without You "thinking" twice about it.
So, the brain is an intrinsic part of the body - and strangely enough, the other way around too. Using access control between such closely related entities forfeit their claim of relationship. If you do need access control, then you need to separate the classes more into truly distinct units. Until then, they are the same unit. A driving example for further studies would be to look at how a Java Iterator usually is implemented.
Unlimited access from enclosing code to nested code makes it, for the most part, rather useless to add access modifiers to fields and methods of a nested type. Doing so is adding clutter and might provide a false sense of safety for new comers of the Java programming language.
An IMHO important use case for inner classes is the factory pattern.
The enclosing class may prepare an instance of the inner class w/o access restrictions and pass the instance to the outside world, where private access will be honored.
In contradiction to abyx declaring the class static doesn't change access restrictions to the enclosing class, as shown below. Also the access restrictions between static classes in the same enclosing class are working. I was surprised ...
class MyPrivates {
static class Inner1 { private int test1 = 2; }
static class Inner2 { private int test2 = new Inner1().test1; }
public static void main(String[] args) {
System.out.println("Inner : "+new Inner2().test2);
}
}
Access restrictions are done on a per class basis. There is no way for a method declared in a class to not be able to access all of the instance/class members. It this stands to reason that inner classes also have unfettered access to the members of the outer class, and the outer class has unfettered access to the members of the inner class.
By putting a class inside another class you are making it tightly tied to the implementation, and anything that is part of the implementation should have access to the other parts.
The logic behind inner classes is that if you create an inner class in an outer class, that's because they will need to share a few things, and thus it makes sense for them to be able to have more flexibility than "regular" classes have.
If, in your case, it makes no sense for the classes to be able to see each other's inner workings - which basically means that the inner class could simply have been made a regular class, you can declare the inner class as static class XYZ. Using static will mean they will not share state (and, for example new ABC().new XYZ() won't work, and you will need to use new ABC.XYZ().
But, if that's the case, you should think about whether XYZ should really be an inner class and that maybe it deserves its own file. Sometimes it makes sense to create a static inner class (for example, if you need a small class that implements an interface your outer class is using, and that won't be helpful anywhere else). But at about half of the time it should have been made an outer class.
Inner class is regarded as an attribute of the Outer class. Therefore, no matter the Inner class instance variable is private or not, Outer class can access without any problem just like accessing its other private attributes(variables).
class Outer{
private int a;
class Inner{
private int b=0;
}
void outMethod(){
a = new Inner().b;
}
}
Because your main() method is in the ABC class, which can access its own inner class.