Nested Classes in Java: A Comprehensive Guide
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.
Syntaxclass 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.
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. |