Quick Refresh : Java : Inner Class

 


Inner class in java : Inner class means one class which is a member of another class. There are basically four types of inner classes in java.

1) Nested Inner class
2) Method Local inner classes
3) Anonymous inner classes
4) Static nested classes

(1) Nested Inner class can access any private instance variable of outer class. Like any other instance variable, we can have access modifier private, protected, public and default modifier. Like class, interface can also be nested and can have access specifiers.

class Outer {
   // Simple nested inner class
   class Inner {
      public void show() {
           System.out.println("In a nested class method");
      }
   }
}
class Main {
   public static void main(String[] args) {
       Outer.Inner in = new Outer().new Inner();
       in.show();
   }
}
Output:
In a nested class method

As a side note, 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. For example the following program doesn’t compile.

class Outer {
   void outerMethod() {
      System.out.println("inside outerMethod");
   }
   class Inner {
      public static void main(String[] args){
         System.out.println("inside inner class Method");
      }
   }
}
Output:
Error illegal static declaration in inner class
Outer.Inner public static void main(String[] args)
modifier ‘static’ is only allowed in constant
variable declaration 


An interface can also be nested and nested interfaces have some interesting properties.

(2) Method Local inner classes: Inner class can be declared within a method of an outer class. In the following example, Inner is an inner class in outerMethod().
class Outer {
    void outerMethod() {
        System.out.println("inside outerMethod");
        // Inner class is local to outerMethod()
        class Inner {
            void innerMethod() {
                System.out.println("inside innerMethod");
            }
        }
        Inner y = new Inner();
        y.innerMethod();
    }
}
class MethodDemo {
    public static void main(String[] args) {
        Outer x = new Outer();
        x.outerMethod();
    }
}
Output
Inside outerMethod
Inside innerMethod

Method Local inner classes can’t use local variable of outer method until that local variable is not declared as final. For example, the following code generates compiler error (Note that x is not final in outerMethod() and innerMethod() tries to access it)

class Outer { 

   void outerMethod() {
      int x = 98;
      System.out.println("inside outerMethod");
      class Inner {
         void innerMethod() {
            System.out.println("x= "+x);
         }
      }
      Inner y = new Inner();
      y.innerMethod();
   }
}
class MethodLocalVariableDemo {
   public static void main(String[] args) {
      Outer x=new Outer();
      x.outerMethod();
   }
}
Output:

local variable x is accessed from within inner class;
needs to be declared final
Note : Local inner class cannot access non-final local variable till JDK 1.7. Since JDK 1.8, it is possible to access the non-final local variable in method local inner class.

But the following code compiles and runs fine (Note that x is final this time)

class Outer {
   void outerMethod() {
      final int x=98;
      System.out.println("inside outerMethod");
      class Inner {
         void innerMethod() {
            System.out.println("x = "+x);
         }
      }
      Inner y = new Inner();
      y.innerMethod();
   }
}
class MethodLocalVariableDemo {
    public static void main(String[] args){
      Outer x = new Outer();
      x.outerMethod();
    }
}
Output-:
Inside outerMethod
X = 98 


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.
Method local inner class can’t be marked as private, protected, static and transient but can be marked as abstract and final, but not both at the same time.

(3) Static nested classes: Static nested classes are not technically an inner class. They are like a static member of outer class.
class Outer {
   private static void outerMethod() {
     System.out.println("inside outerMethod");
   }
     
   // A static inner class
   static class Inner {
     public static void main(String[] args) {
        System.out.println("inside inner class Method");
        outerMethod();
     }
   }
 
}
Output
inside inner class Method
inside outerMethod

(4) Anonymous inner classes: Anonymous inner classes are declared without any name at all. It is an inner class without a name and for which only a single object is created. An anonymous inner class can be useful when making an instance of an object with certain “extras” such as overloading methods of a class or interface, without having to actually subclass a class.Anonymous inner class are mainly created in two ways:

  • Class (may be abstract or concrete)
  • Interface

a) As subclass of specified type
class Demo {
   void show() {
      System.out.println("i am in show method of super class");
   }
}
class Flavor1Demo {   
   //  An anonymous class with Demo as base class
   static Demo d = new Demo() {
       void show() {
           super.show();
           System.out.println("i am in Flavor1Demo class");
       }
   };
   public static void main(String[] args){
       d.show();
   }
}
Output
i am in show method of super class
i am in Flavor1Demo class 


In the above code, we have two class Demo and Flavor1Demo. Here demo act as super class and anonymous class acts as a subclass, both classes have a method show(). In anonymous class show() method is overridden.

a) As implementer of the specified interface
class Flavor2Demo {  
    // An anonymous class that implements Hello interface
    static Hello h = new Hello() {
        public void show() {
            System.out.println("i am in anonymous class");
        }
    };
 
    public static void main(String[] args) {
        h.show();
    }
}
 
interface Hello {
    void show();
}
Output:
i am in anonymous class

Difference between Normal/Regular class and Anonymous Inner class:

  • A normal class can implement any number of interfaces but anonymous inner class can implement only one interface at a time.
  • A regular class can extend a class and implement any number of interface simultaneously. But anonymous Inner class can extend a class or can implement an interface but not both at a time.
  • For regular/normal class, we can write any number of constructors but we cant write any constructor for anonymous Inner class because anonymous class does not have any name and while defining constructor class name and constructor name must be same.

Accessing Local Variables of the Enclosing Scope, and Declaring and Accessing Members of the Anonymous Class
Like local classes, anonymous classes can capture variables; they have the same access to local variables of the enclosing scope:

  • An anonymous class has access to the members of its enclosing class.
  • An anonymous class cannot access local variables in its enclosing scope that are not declared as final or effectively final.
  • Like a nested class, a declaration of a type (such as a variable) in an anonymous class shadows any other declarations in the enclosing scope that have the same name.

Anonymous classes also have the same restrictions as local classes with respect to their members:

  • We cannot declare static initializers or member interfaces in an anonymous class.
  • An anonymous class can have static members provided that they are constant variables.

Note that you can declare the following in anonymous classes:

  • Fields
  • Extra methods (even if they do not implement any methods of the supertype)
  • Instance initializers
  • Local classes

Comments

Popular posts from this blog

Ramoji Film City, Hyderabad, India

Ashtavinayak Temples | 8 Ganpati Temples of Maharashtra | Details Travel Reviews

Quick Refresh : Hibernate