Nested Classes in Java: A Comprehensive Guide

Rumman Ansari   Software Engineer   2024-07-04 04:51:32   8337  Share
Subject Syllabus DetailsSubject Details
☰ TContent
☰Fullscreen

Table of Content:

A class defined within another class is known as Nested class. The scope of the nested class is bounded by the scope of its enclosing class.

We use inner classes to logically group classes and interfaces in one place so that it can be more readable and maintainable.

Syntax
 class Outer{
//class Outer members

class Inner{
//class Inner members
}

} //closing of class Outer
 

Advantage of Java inner classes

There are basically three advantages of inner classes in java. They are as follows:

  • Nested classes represent a special type of relationship that is it can access all the members (data members and methods) of outer class including private.
  • Nested classes are used to develop more readable and maintainable code because it logically groups classes and interfaces in one place only.
  • Code Optimization: It requires less code to write.

Types of Nested Class

Nested classes are divided into two types ?

  • Non-static nested classes ? These are the non-static members of a class.

  • Static nested classes ? These are the static members of a class.

types of nested class

static Nested Class

If the nested class i.e the class defined within another class, has static modifier applied in it, then it is called as static nested class.


A static nested class is one that has the static modifier applied. Also we can saystatic inner class is a nested class which is a static member of the outer class. Because it is static, it must access the members of its enclosing class through an object. That is, it cannot refer to members of its enclosing class directly. Because of this restriction, static nested classes are seldom used.

It can be accessed without instantiating the outer class, using other static members. Just like static members, a static nested class does not have access to the instance variables and methods of the outer class. The syntax of static nested class is as follows

Syntax

class OuteClassr {
   static class NestedClass {
   }
}

Instantiating a static nested class is a bit different from instantiating an inner class. The following program shows how to use a static nested class.

Program

  public class OuterClass {
   static class NestedClass {
      public void message() {
         System.out.println("This is my nested class");
      }
   }

   public static void main(String args[]) {
      OuterClass.NestedClass nested = new OuterClass.NestedClass();
      nested.message();
   }
}
  

Output

  This is my nested class
Press any key to continue . . .
  

It can use them only through an object reference.They are accessed using the enclosing class name.

OuterClass.StaticNestedClass

For example, to create an object for the static nested class, use this syntax:

OuterClass.StaticNestedClass nestedObject =
     new OuterClass.StaticNestedClass();

Program

// Java program to demonstrate accessing
// a static nested class

// outer class
class OuterClass
{
    // static member
    static int outer_x = 20;

    // instance(non-static) member
    int outer_y = 30;

    // private member
    private static int outer_private = 40;

    // static nested class
    static class StaticNestedClass
    {
        void display()
        {
            // can access static member of outer class
            System.out.println("outer_x = " + outer_x);

            // can access display private static member of outer class
            System.out.println("outer_private = " + outer_private);

            // The following statement will give compilation error
            // as static nested class cannot directly access non-static membera
            // System.out.println("outer_y = " + outer_y);

        }
    }
}

// Driver class
public class StaticNestedClassDemo
{
    public static void main(String[] args)
    {
        // accessing a static nested class
        OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

        nestedObject.display();

    }
}
  

Output

outer_x = 20
outer_private = 40
Press any key to continue . . .
  

Non-static Nested class

Non-static Nested class is the most important type of nested class.

Inner Class

The most important type of nested class is the inner class. An inner class is a non-static nested class. It has access to all of the variables and methods of its outer class and may refer to them directly in the same way that other non-static members of the outer class do.

But the reverse is not true, that is, Outer class cannot directly access members of Inner class. Inner class can be declared private, public, protected, or with default access whereas an Outer class can have only public or default access.


The following program illustrates how to define and use an inner class. The class named Outer has one instance variable named outer_x, one instance method named test( ), and defines one inner class called Inner.

Program

// Demonstrate an inner class.
class Outer {
	int outer_x = 121;
	void msg() {
		InnerClass inner = new InnerClass();
		inner.display();
		}

// this is an inner class
class InnerClass {
void display() {
	System.out.println("display: outer_x = " + outer_x);
	}
	}
}
class InnerClassDemo {
	public static void main(String args[]) {
	Outer outer = new Outer();
	outer.msg();
	}
}
  

Output

display: outer_x = 121
Press any key to continue . . .
  

Note: One more important thing to notice about an Inner class is that it can be created only within the scope of Outer class. Java compiler generates an error if any code outside Outer class attempts to instantiate Inner class directly.

Member inner class.

A non-static Nested class that is created outside a method is called Member inner class.

Example of Inner class(Member class)

class Outer
{
 public void display()
 {
  Inner in=new Inner();
  in.show();
 }

 class Inner
 {
  public void show()
  {
   System.out.println("Inside inner");
  } 
 }
}

class Test
{
 public static void main(String[] args)
 {
  Outer ot=new Outer();
  ot.display();
 }
}

Output :

Inside inner

Method-local Inner Class

In Java, we can write a class within a method and this will be a local type. Like local variables, the scope of the inner class is restricted within the method.
A method-local inner class can be instantiated only within the method where the inner class is defined. The following program shows how to use a method-local inner class.

Program

class OuterclassTest {
   // instance method of the outer class
   void my_Method() {
      int num = 21;

      // method-local inner class
      class MethodInnerClass {
         public void print() {
            System.out.println("This is method inner class "+num);
         }
      } // end of inner class

      // Accessing the inner class
      MethodInnerClass inner = new MethodInnerClass();
      inner.print();
   }

   public static void main(String args[]) {
      OuterclassTest outer = new OuterclassTest();
      outer.my_Method();
   }
}
  

Output

This is method inner class 21
Press any key to continue . . .
  

Example of Inner class inside a method(local inner class)

class Outer
{
 int count;
 public void display()
 {
  for(int i=0;i<5;i++)
  {
   class Inner       //Inner class defined inside for loop
   {        
    public void show()  
    {
     System.out.println("Inside inner "+(count++));
    } 
   }
   Inner in=new Inner();
   in.show();
  }
 }
}

class Test
{
 public static void main(String[] args)
 {
  Outer ot=new Outer();
  ot.display();
 }
}

Output :

Inside inner 0
Inside inner 1
Inside inner 2
Inside inner 3
Inside inner 4

Example of Inner class instantiated outside Outer class

class Outer
{
 int count;
 public void display()
 {
  Inner in=new Inner();
  in.show();
 }

 class Inner
 {
  public void show()
  {
   System.out.println("Inside inner "+(++count));
  } 
 }
}

class Test
{
 public static void main(String[] args)
 {
  Outer ot=new Outer();
  Outer.Inner in= ot.new Inner();
  in.show();
 }
}

Output :

Inside inner 1

Anonymous Inner Class

An inner class declared without a class name is known as an anonymous inner class. In case of anonymous inner classes, we declare and instantiate them at the same time. Generally, they are used whenever you need to override the method of a class or an interface. The syntax of an anonymous inner class is as follows ?

Syntax

AnonymousInner an_inner = new AnonymousInner() {
   public void my_method() {
      ........
      ........
   }   
};

The following program shows how to override the method of a class using anonymous inner class.

Program

abstract class AnonymousInner {
   public abstract void message();
}

public class OuterClass {

   public static void main(String args[]) {
      AnonymousInner inner = new AnonymousInner() {
         public void message() {
            System.out.println("This is an example of anonymous inner class");
         }
      };
      inner.message();
   }
}
  

Output

This is an example of anonymous inner class
Press any key to continue . . .
  

In the same way, you can override the methods of the concrete class as well as the interface using an anonymous inner class.

Anonymous Inner Class as Argument

Generally, if a method accepts an object of an interface, an abstract class, or a concrete class, then we can implement the interface, extend the abstract class, and pass the object to the method. If it is a class, then we can directly pass it to the method.

But in all the three cases, you can pass an anonymous inner class to the method. Here is the syntax of passing an anonymous inner class as a method argument ?

obj.my_Method(new My_Class() {
   public void Do() {
      .....
      .....
   }
});

The following program shows how to pass an anonymous inner class as a method argument.

Program

// interface
interface Display {
   String greet();
}

public class My_class {
   // method which accepts the object of interface Display
   public void displayMessage(Display m) {
      System.out.println(m.greet() +
         ", This is an example of anonymous inner class as an argument");
   }

   public static void main(String args[]) {
      // Instantiating the class
      My_class obj = new My_class();

      // Passing an anonymous inner class as an argument
      obj.displayMessage(new Display() {
         public String greet() {
            return "welcome to atnyla";
         }
      });
   }
}
  

Output

welcome to atnyla, This is an example of anonymous inner class as an argument
Press any key to continue . . .
  
interface Animal
{
 void type();
}
public class ATest {
 public static void main(String args[])
 {
  Animal an = new Animal(){         //Annonymous class created
  public void type()
  {
   System.out.println("Annonymous animal"); 
  }
 };
  an.type();      
 }
}

 

Output :

Annonymous animal

Here a class is created which implements Animal interace and its name will be decided by the compiler. This annonymous class will provide implementation of type() method.

Overview

Type Description
Member Inner Class A class created within class and outside method.
Anonymous Inner Class A class created for implementing interface or extending class. Its name is decided by the java compiler.
Local Inner Class A class created within method.
Static Nested Class A static class created within class.
Nested Interface An interface created within class or interface.