Inner Class in java

To do :

  • Are inner classes inherited and extendable?
  • is nested interface possible?
  • Final and abstract inner class
  • list of access modifiers applicable on inner classes

What is inner class ?

  • Inner class means a class which is a member of another class.
  • Java Inner class instance has access to all member of the outer class(Public, Private & Protected)
  • Nested classes enable you to logically group classes that are only used in one place, increase the use of encapsulation, and create more readable and maintainable code. 

Why inner class ?

  • The purpose of nested classes is to group classes that belong together, which makes your code more readable and maintainable. Why to implement a class outside if its objects are only intended to be part of an outer object. Its easy to define the class within another class if the use is only local.
  • Inner classes are used to get functionality which can get an object better than method.
  •  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.
  • Increases encapsulation : Advantage of inner class is that they can be hidden from the other classes in the same package and still have the access to all the members (private also) of the enclosing class.Example : Consider two top-level classes, A and B, where B needs access to members of A that would otherwise be declared private. By hiding class B within class A, A’s members can be declared private and B can access them. In addition, B itself can be hidden from the outside world.
  •  Local classes, anonymous classes, and lambda expressions also impart these advantages; however, they are intended to be used for more specific situations
  • Inner classes are made to achieve multiple inheritance also.
  • Inner classes are used when they are useful in class context and separate logic inside classes.

There are types of inner classes in java :

  • Nested Inner class
  • Method local inner class
  • Anonymous inner class
  • Static nested class
  • Nested inner interface

Nested Inner Class

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

class Outer {
	// Simple nested inner class
	class Inner {
		public void show() {
			System.out.println("In a nested class method");
		}
	}
}
  • We can’t have static method in a nested inner class because an inner class is implicitly associated with an object of its outer class so it cannot define any static method for itself. 
  • Static method or static variable cannot be present inside a nested innner class since inner class is already a part of instance of outerclass.

Method local inner class

  • Inner class can be declared within a method of an outer class.
  • Method Local inner classes can’t use local variable of outer method.(But can access if the local variable is final from java 1.8)
  • The main reason we need to declare a local variable as a final is that local variable lives on stack till method is on the stack but there might be a case the object of inner class still lives on the heap.

Example :

public class MethodInnerClass {
	public static void main(String[] args) {
		Outer x = new Outer();
		x.outerMethod();
	}
}

class Outer {
	void outerMethod() {
		final int x = 98;
		System.out.println("inside outerMethod");
		class Inner {
			void innerMethod() {
				System.out.println("inside methodInnerClass's method");
				System.out.println("x = " + x);
			}
		}
		Inner y = new Inner();
		y.innerMethod();
	}
}

Internally Generated Class : Outer$Inner.class

protected static class Outer$Inner{
	Outer$Inner(){}
	void print() {
		System.out.println("instance method"+y);
	}
	static void printStatic() {
		System.out.println("Static method");
	}
}

Anonymous inner class

  • Anonymous inner class is a class without name and for which only a single object is created.
  • Anonymous inner class are created when we have to create a class just for one use i.e overriding an existing class for some specific method.
  • Anonymous inner class can be created from a Abstract class, concrete class or an Interface.

Example :

public class AnonymousInnerClassDemo {
	public static void main(String[] args) {
		Demo demo1 = new Example();
		demo1.printMessage();
		Demo demo2 = new Demo() {
			public void printMessage() {
				System.out.println("Message from anonymous inner class");
			}
		};
		demo2.printMessage();
	}
}
interface Demo {
	public void printMessage();
}
class Example implements Demo{

	@Override
	public void printMessage() {
		System.out.println("Message from exampe class");
	}
	
}

Static inner class

Static nested classes are not technically an inner class. They are like a static member of outer class.

Static inner class in the start looks very confusing but when you the basic idea you will under stand it in a better way :
a. These class cannot access non static data members and methods of the outer class.
b. You can create object of the static inner class without the object of outer class
c. You can have static and non static methods and variables inside static inner class just like any other inner class
d. To access the static data members of static inner class you need not have object of outer or static inner class.
e. To access the non static data members you need not have object out the outer class but need an object of static inner class.

public class StaticInnerClass {
	public static void main(String[] args) {
		//Point (b)
		Outer.Inner obj = new Outer.Inner(); //No Outer() is added since it is static
		//Point (d)
		Outer.Inner.printStatic();//Can also be written as Inner.printStatic();
		//Point (e)
		obj.print();
	}
}
class Outer{
	int x;
	static int y;
	protected static class Inner{
		// Point (c) non static
		void print() {
			//Point (a)
			//System.out.println("instance method"+x); compilation error
			System.out.println("instance method"+y);
		}
		// Point (c) static
		static void printStatic() {
			System.out.println("Static method");
		}
	}
}

Inner Interface

  • An interface which is declared inside another interface or class is called nested interface or inner interface
  • Since nested interface cannot be accessed directly, the main purpose of using them is to resolve the namespace by grouping related interfaces (or related interface and class) together.
  • This way, we can only call the nested interface by using outer class or outer interface name followed by dot( . ), followed by the interface name.
  • Example: Entry interface inside Map interface is nested. Thus we access it by calling Map.Entry.
  • Class nested inside an interface and vice-versa is also allowed in java

Note :

  • Nested interfaces are static by default. You don’t have to mark them static explicitly as it would be redundant.
  • Nested interfaces declared inside class can take any access modifier, however nested interface declared inside interface is public implicitly.

Example 1 : Nested interface inside an interface

interface MyInterfaceA{  
    void display();  
    interface MyInterfaceB{  
        void myMethod();  
    }  
}  
      
class NestedInterfaceDemo1 
    implements MyInterfaceA.MyInterfaceB{  
     public void myMethod(){
         System.out.println("Nested interface method");
     }  
      
     public static void main(String args[]){  
         MyInterfaceA.MyInterfaceB obj=
                 new NestedInterfaceDemo1(); 
      obj.myMethod();  
     }  
}

Example 2 : Nested Interface, inside a class

class MyClass{  
    interface MyInterfaceB{  
        void myMethod();  
    }
}  
    
class NestedInterfaceDemo2 implements MyClass.MyInterfaceB{  
     public void myMethod(){
         System.out.println("Nested interface method");
     }  
    
     public static void main(String args[]){  
        MyClass.MyInterfaceB obj=
               new NestedInterfaceDemo2();  
        obj.myMethod();  
     }  
}

Internal Working of Inner Class in java

When you write below program(Outer.java) and compile it two .class files are created :
Outer.class
Outer$Inner.class

File : Outer.java

class Outer {
	private int y = 9;
	class Inner{
		int getValue() {
			return y;
		}
	}
}

File created after compiling Outer.class and Outer$Inner.class is created :

Outer.class

class Outer {
  private int y = 9;
  
  class Inner {
    int getValue() {
      return Outer.this.y;
    }
  }
}

Outer$Inner.class

class Inner {
  int getValue() {
    return Outer.access$0(Outer.this);
  }
}

Read Me :

https://docs.oracle.com/javase/tutorial/java/javaOO/whentouse.html
https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
https://stackoverflow.com/questions/18396016/when-to-use-inner-classes-in-java-for-helper-classes
https://www.geeksforgeeks.org/inner-class-java/
https://www.w3schools.com/java/java_inner_classes.asp
https://www.geeksforgeeks.org/anonymous-inner-class-java/

Some interesting Questions :

  • Why inner class?
  • Internal working of inner class
  • When is the perfect opportunity to create inner class
  • Compiled inner class
  • memory space of static nested class
  • Are inner classes inherited and extendable?
  • is nested interface possible?
  • Final and abstract inner class
  • list of access modifiers applicable on inner classes

Leave a Comment