Thursday, December 22, 2011

Inner class and Anonymous classes in Java

Nested Classes in Java

A nested class is a class defined inside the definition (body) of another enclosing class. 
A nested class can be of two types - static or non-static. A nested class is treated as a 
member of the enclosing class. A static nested class is not very tightly integrated with 
the enclosing class and it lives its own independent life as well i.e., a static nested 
class can be instantiated like any other class from just about anywhere. 
They are defined inside the definition of an enclosing class just to get a logical grouping 
of the classes, which in turn increases readability and provides better packaging convenience.

A static nested class can't directly access the members of the enclosing class. Like any other 
top-level class it needs to access the members of the enclosing class via object references only.

Example: a static nested class

class EnclosingClass {
 ...
 ...
 static class StaticNestedClass{
  //...definition of the static nested class
  ...
  ...
 }
 ...
 ...
}

A static nested class is accessed using the enclosing class name as follows:
EnclosingClass.StaticNestedClass staticNestedObjectRef = new EnclosingClass.StaticNestedClass();

Inner Classes in Java
A non-static nested class is called an inner class and it's tightly integrated with the enclosing 
class unlike a static nested class. An inner class instance can't exist independent to the enclosing 
class instance. An inner class instance always exist within the instance of the enclosing class. 
Since, it's always associated with the enclosing class instance and it has direct access to all the 
members of the enclosing class - even the private members.

Example: an inner class
class EnclosingClass {
 ...
 ...
 class InnerClass{
 //...definition of the inner class
 ...
 ...
 }
 ...
 ...
}

Since, an instance of an inner class always exists within an instance of the enclosing class, hence 
we must instantiate the enclosing class first and then on that instance we can instantiate the inner class:-

EnclosingClass enclosingObjectRef = new EnclosingClass();
EnclosingClass.InnerClass innerObjectRef = enclosingObjectRef.new InnerClass();

Can an Inner Class declare static members?
No. Because any instance of an inner class is always associated with an instance of the enclosing class.

Can we have private or protected access for classes in Java?
Yeah... but only for nested classes and not for top-level classes. Nested classes 
are treated as members of the enclosing classes and hence we can specify any of the 
four access specifiers - private, package, protected, or public. We don't have this luxury 
with top-level classes - they can only be declared public or package.

Local Inner Classes in Java
If an inner class has been defined within a code block (typically within the body of a method), 
then such an inner class is called a local inner class. A local inner class is not a member 
of the enclosing class and hence it can not have any access specifier. A local inner class 
will have access to all the members of the enclosing class and it'll have access to the local 
final variables in the scope it's defined.

Example: a typical local inner class
public class EnclosingClass{
...
 public methodName(){
  //...definition of the local inner class
   class LocalInnerClass {
    ...
   }
 ...
 }
}

Anonymous Inner Classes in Java
If an inner class has been declared without a name and within a code block (typically within the 
body of a method) then such an inner class is called an anonymous inner class. 
Since such an inner class doesn't have a name associated, so it'll be accessible only at the point 
where it is defined.

Example: a very common usage of an anonymous inner class
import java.awt.event.*;
public class GUI extends JFrame{
...
    public void buildComponents(){
        ...
        button1 = newJButton();
        ...
        button1.addActionListener(new ActionListener(){
          public void actionPerformed(java.awt.event.ActionEvent ae){
           ...
           ...
          }
        });
        ...
        ...
   }
}

Since, an anonymous inner class doesn't have a name, so it can't have a named constructor. 
But, it can have an instance initializer. Access rules for anonymous inner classes are same as that of 
local inner classes. Similar to a local inner class, an anonymous inner class can also not have 
any access specifier attached to it.

Are anonymous inner classes same as local inner classes?
Yeah..., an anonymous inner class is a local inner class in all means except that it doesn't 
have a name and hence it can't be used at any other point except at the point where it has 
been defined. The other difference is that it can't have a named constructor again for the 
same reason that it doesn't have a name.

No comments:

Post a Comment