Way2Java

Inner classes Java

Introduction to Inner classes Java

JDK 1.1 introduced a new type of classes known as inner classes. All the classes you have done so far are known as top-level classes. A class written inside another class is known as "inner class" or "nested class". That is, an inner class is enclosed within another class. Inner classes give more accessibility and scope restrictions for other classes.

The class which encloses is known as outer class and getting enclosed is known as inner class. Outer class is known as top-level class. The classes of a package are all top-level classes.

Types of Inner Classes Java

There are four styles of creating an inner class.

  1. Static member classes
  2. Member classes
  3. Local classes
  4. Anonymous classes

1. Static Member Classes

Here, the inner class is declared as static. Static inner classes are less used. Following program illustrates.

public class FirstOne
{
  static class SecondOne
  {
    public static void area(int x)   
    {
      System.out.println("Area is " + (Math.round(3.14*x*x)));
    } 				
  } 		
  public static void main(String args[] )  
  {
    FirstOne.SecondOne.area(10);
  }
}

The inner class SecondOne is declared as static member of outer class FirstOne and includes a static method area(). When we compile the above program we get two .class files as follows.

  1. FirstOne.class
  2. FirstOne$SecondOne.class

The .class file of SecondOne inner class is placed within the outer class, FirstOne. The other classes cannot access directly the SecondOne and should go through FirstOne.

FirstOne.SecondOne.area(10);

As the SecondOne is static, it is called with FirstOne directly. The SecondOne scope is within the FirstOne.

2. Member Classes

Here, the inner class is not declared as static. It is declared within the body of the outer class (not inside the method of outer class). Following are the scope rules.

  1. The outer class members (variables) can be accessed by inner class.
  2. The inner class members cannot be accessed by outer class.
  3. Inner class members can be accessed by inner class only.

Following program illustrates the above scope rules.

public class First    // Top-level class; outer class or enclosing class
{
  int price = 100;   // variable of outer class

  class Second       // inner class as a member of outer class
  {
    int rate = 200;              // variable of inner class
          
    public void display()        // inner class method
    {
      System.out.println("price from display() method: " + price);
      System.out.println("rate from display method: " + rate );
    }
  }                              // inner class closes
   
  public void show()             // outer class method
  {
    System.out.println("pirce from show() method: " + price);
    // System.out.println("y from outer method: " + y);  // raises compilation error, scope problem
  }
  public static void main(String args[])    
  {
    First f1 = new First();
    First.Second fs = new First( ).new Second();
    f1.show();
    fs.display();
  }
}

In the above code, First is outer class and Second is inner class. price is a variable of outer class and rate is a variable of inner class. By the scope rules, Second can access price but First cannot access rate .

When the above code is compiled, two .class are obtained as follows.

  1. First.class
  2. First$Second.class

As you can observe, the inner class, Second exists within the context of outer class, First.

First.Second fs = new First( ).new Second();

The Second class object cannot be created directly and must be done through the outer class, First.

The above statement can be modified as follows.

First.Second fs = f1.new Second();

The outer class object is created with the help of inner class object. Finally, inner class can access all the static and non-static fields of outer class (including private fields) and the inner class object cannot be instantiated directly and should be done through outer class object.

3. Local Classes

A local class is simply an inner class but declared within the method of outer class (earlier, the inner class exists directly in the body of the outer class but now exists inside a method). Here the rules of accessibility are, the inner class can access, anyhow, its own members and only the final parameters of the enclosing method .

Following program illustrates.

public class Father   
{
  double price = 10.5;          // outer class field (variable)
  public void area(int x , final int y)   // outer class method
  {	
    int k = x + y;        //  non-final variable of outer class
    final int m = x * y;  // final variable of outer class
		
    class Son  	// inner class inside the method area() of outer class
    {
      public void perimeter()
      {
        // System.out.println("x is " + x);	          // error as x non-final
        System.out.println("y is " + y);            // no error as y is final
        //  System.out.println("k is " + k);            // error as k is non-final
        System.out.println("m is " + m);           // no error as m is final
        System.out.println("price  is " + price);  
      }                               // price is not final, but works as it is a field (not parameter) 
    }                                // inner class closes
    Son s1 = new Son();
    s1.perimeter();
  }                                 // outer method closes
  public static void main(String args[])  
  {
    Father f1 = new Father();
    f1.area(10, 20);
  }
}

In the above code, the perimeter() method of inner class Son can access the final parameters of area(), the method of outer class Father. That is, the perimeter() method can access the final variables y and m of area(). But, the inner class can access the price, non-final variable of outer class as it is a field declared in the body of the outer class and not within the method.

When we compile the above program, we get the following classes.

  1. Father.class
  2. Father$1Son.class

Observe, it is $1 and not $.

4, Anonymous Inner Class

An anonymous inner class, as the name indicates, does not have a name. As it does not contain a name, it must be instantiated at the time of defining it. This type of anonymous classes is mostly used in event handling mechanism of AWT. Followng snippet of code is used to close the frame window.

addWindowListener( new WindowAdapter()   
           {
	           public void windowClosing(WindowEvent e)  
                   {
		         Sytem.exit( 0 ) ;
	           }
	    } 
       ) ;

In the above code, an anonymous inner class of WindowAdapter is used. The advantage of anonymous inner classes is better readability as all the code exists at the time of declaration only, all at one place. The disadvantage is the code cannot be used elsewhere (no reusability).

Advantages – Inner Classes

Following list gives the advantages of inner classes.

  1. Better accessibility restrictions. The inner classes are controlled through outer class instances.
  2. The life of inner class is controlled by outer class. Inner classes can use
    composition but through outer class.
  3. We can make a logical group of classes. If a class is useful particularly to only one another class, the class can be declared as inner class.
  4. Encapsulation is better implemented. The inner class members are hidden from other classes.
  5. The maintainability is easier as the code is closer to other class.