Tuesday, June 14, 2016

Nested classes

What does it mean by nested class ?

A class within another class called nested classes. You can define one class within another class as follows.

class Outerclass {
      ...
      class Inner{
          ...
      }
}

What is the purpose of using nested class ?

  • To improve code readability and maintainability.
  • This is the way of grouping classes where all classes are used in one place.
  • To improve code optimization (By increasing encapsulation).
  • This can be used to hide implementation details.

Types of nested classes 



Static nested classes

  • If you create a static class inside of any class is called static nested class.
  • These are called "Top level inner classes".
  • It can access any data of outer class including which are with private access.
  • It can't access to non-static data.

class Outerclass {

    static int i = 10;

    static class StaticInner {
       static void showMessage(){
          System.out.println("Value :" + i);
       }
    }
 
    public static void main(String[] args) {
       Outerclass.StaticInner.showMessage();
    }
}


Non static nested classes (Inner classes)

  • If you create a non static class inside a class but outside of a method is called inner classes.
  • As you can see in above diagram, there are two types of inner classes.


class Outerclass {

   static int i = 10;

   class NonStaticInner {
      void showMessage(){
          System.out.println("Value :" + i);
      }
   }  
 
   public static void main(String[] args) { 
      Outerclass outer = new Outerclass();
      Outerclass.NonStaticInner inner = outer.new NonStaticInner();
      inner.showMessage();
   }
}

Local inner classes

  • A class which is created inside of a method is called local inner classes.
  • You may look at the following example.

public class LocalInnerClassDemo {
 
   void display(){
       int i = 10;
  
       class LocalInner{
           void showMessage(){
                System.out.println("Value : " + i);
           }
       }
       LocalInner inner = new LocalInner();
       inner.showMessage();
   }
 
   public static void main(String[] args) {
       LocalInnerClassDemo classDemo = new LocalInnerClassDemo();
       classDemo.display();
   }
}


Anonymous inner classes

  • This looks same as local inner classes, but anonymous inner classes don't have a class name.
  • Using anonymous classes, you can declare and instantiate a class at the same time.
  • Anonymous classes can be used to concise your code and make it more readable.
  • Anonymous classes can be created using two ways.
    1. Using a class (abstract class or concrete class)
    2. Using an interface

Using a class

abstract class Demo{
     abstract void display();
}

public class AnonymousClassDemo {
 
     public static void main(String[] args) {

         Demo demo = new Demo() {
             void display() {
                 System.out.println("Anonymous Demo");
             }
         };
     demo.display();
     }
}


Using an interface


interface Demo{
    abstract void display();
}

public class AnonymousClassDemo {
 
    public static void main(String[] args) {

        Demo demo = new Demo() {
           public void display() {
               System.out.println("Anonymous Demo");
           }
        }; 
        demo.display();
    }
}



You may need to consider about following things when you create anonymous classes.

  • You have to extend to a class or implement by using a interface.
  • You need to use "new".
  • Anonymous class is just like a expression.
  • You can create local classes and methods in anonymous classes.
  • But you can't create constructors in anonymous classes.

Inner classes in your matters

Inner classes are really useful when creating GUI applications. Think, you just want to make an ActionListener when you click on a button. Once you get it you may think to do it as follows.

myButton.addActionListener(instance);


But unfortunately you forgot that you cannot create objects without implementing to ActionLesterner interface. Then the easiest way to do it, using inner classes.

myButton.addActionListener
(
    new ActionListener()
    {
        public void actionPerformed( ActionEvent e )
        {
            implementation
        }
    }
);