Tuesday, 14 May 2013

Inner classes in Java


Nested Classes or Inner Classes

A class defined inside a class is known as inner class and also known as nested class. It is possible to apply the public, default, abstract, final, strictfp, private, protected and static modifier on inner class.
If we apply public on inner class, it is possible to access outside. Inner classes can access all the members of outer class. Even inner classes can access private members of outer class. Inner classes are available with java 1.1. 


The syntax for inner classes is:-

class outerClass{
class innerClass{
}
}

In Java, if we declare a static inner class then it is simply known as Nested static class where as NonStatic nested classes are known as inner classes.

Nested classes are divided into two categories:-
  • Static Nested classes
  • Non-Static Nested classes

Non-Static Nested (Inner) classes are divided into 3 categories:-
  •       Method Local Inner class
  •       Member Inner class
  •       Anonymouse Inner class

Properties of Inner class:-
  • If we are using static inner class then we can instantiate it without an outer class instance.
  • Inner class object must have association with outer class instance.
  • Inner class can access all the elements of the outer class.
  • We can define multiple inner classes inside an outer class.
  • If the outer class is public and also the inner class access-specifier is public, then in this case in other classes we can create an instance of the inner class.
  • Inner class objects are not automatically instantiated with an outer class object

Advantage: - Inner and nested classes help in maintenance of code and it also improves encapsulation.

Definitions

  • Static Nested class: - A static class declared inside a class is turned as static nested class. Static inner classes can’t access the non-static members. But it can access static members of the Outer class , even it can access private members of the outer class.

Syntax: -

<modifiers> class NameOfTheOuterClass {
<modifiers> static class <NameOfTheStaticInnerClass> {
            //place the code here
            }
            //place the code here
}
Example:- class outerClass{
            ...
            static class innerClass{
            ...
}
}

When we will compile the above class
  • javac  outerClass.java
After compilation, compiler will generate the below classes:-
  •  outerClass.class
  • outerClass$ innerClass.class

A very good example of Nested Static class: - In J2SDK, HashMap class is containing a nested static class which is Entry<K, V>.

Note: - It does not have access to non-static members/instance variables of the outer class.

Example of Nested Static Class

package com.gaurav.corejava.innerclass;

public class StaticInnerClassTestDemo {
                private static String strPrivateVariable = "MYSELF OUTER CLASS PRIVATE INSTANCE VARIABLE";
                private static String LASTNAME= "KUMAR ";
                static class StaticInnerClass{
                                int x = 100;
                                String strStaticInnerClassVariable = "MYSELF INNER CLASS VARIABLE";
                                StaticInnerClass(){
                                                System.out.println("******************************************");
                                                System.out.println("MYSELF STATIC INNER CLASS ");
                                                //ACCESSING PRIVATE MEMBERS OF THE OUTER CLASS
                                                System.out.println("ACCESSING PRIVATE VARIABLE OF OUTER CLASS :- "+strPrivateVariable);
                                }
                                public String getFullName(String firstName){
                                                return LASTNAME + firstName;
                                }
                }
                                public static void main(String args[]){
                                                StaticInnerClassTestDemo.StaticInnerClass sic =        new StaticInnerClassTestDemo.StaticInnerClass();    
                                                System.out.println("STATIC INNER CLASS STRING VARIABLE :- "+sic.strStaticInnerClassVariable);
                                                System.out.println("STATIC INNER CLASS INT VARIABLE :- "+sic.x);
                                                System.out.println("STATIC INNER CLASS METHOD CALL GETFULLNAME() : - "+sic.getFullName("GAURAV"));
                                }
                }

Result:-
******************************************
MYSELF STATIC INNER CLASS
ACCESSING PRIVATE VARIABLE OF OUTER CLASS :- MYSELF OUTER CLASS PRIVATE INSTANCE VARIABLE
STATIC INNER CLASS STRING VARIABLE :- MYSELF INNER CLASS VARIABLE
STATIC INNER CLASS INT VARIABLE :- 100
STATIC INNER CLASS METHOD CALL GETFULLNAME() : - KUMAR GAURAV

Non-Static Nested (Inner) classes


  • Method Local Inner class or Local inner class: - When a class is declared inside a method is known as Local inner class. This class can be instantiated only within the method. If we need to invoke the methods of the Local inner class then it is mandatory to instantiate this class inside the method. This class can use outer class private members. For Local inner class only default access specifier is allowed and abstract and final modifier is permitted. Local inner class can’t access method variables. It can access only final variables declared inside the method.

Example of Method Local Inner class

package com.gaurav.corejava.innerclass;

public class MethodInnerClassTestDemo {
            private int totalScore = 175;
            private static String strStaticvariable = "MYSELF STATIC VARIABLE ";
            public String getScorerName() {
                        final String manOfTheMatch = "CHRIS GAYLE";
                        String noOfSingles = "TWENTY";
                        final int noOfFours = 12;
                        final int noOfSixes = 15;
                       
                        class MethodInnerClass {
                                    String strBoundaryValue = "NO BOUNDARY";

                                    public String getScoreUsingBoundaries() {
                                                //ACCESSING PRIVATE MEMBER OF THE OUTER CLASS.
                                                System.out.println("ACCESSING PRIVATE VARIABLE, TOTAL SCORE MADE BY SCORER IS : - "
                                                                        + totalScore);
                                                // WE CAN'T ACCESS THE NON FINAL VARIABLE HERE. THIS IS WRONG HERE
                                                // System.out.println("NO OF SINGLES"+noOfSingles);
                                                int totalBoundary = noOfFours + noOfSixes;
                                                if (totalBoundary == 27) {
                                                            strBoundaryValue = "TWENTY SEVEN";
                                                }
                                                System.out.println("ACCESSING CLASS LEVEL STATIC VARIABLE :- "+strStaticvariable);
                                                return strBoundaryValue;
                                    }
                        }
                        MethodInnerClass mic = new MethodInnerClass();
                        System.out
                                                .println("ACCESSING LOCAL INNER CLASS METHOD, TOTAL BOUNDRY HITTED INCLUDING FOUR AND SIX IS : - "
                                                                        + mic.getScoreUsingBoundaries());
                        System.out.println("NUMBER OF SINGLES TAKEN BY SCORER IS : - "
                                                + noOfSingles);
                        return manOfTheMatch;
            }

            public static void main(String args[]) {
                        MethodInnerClassTestDemo mictd = new MethodInnerClassTestDemo();
                        System.out.println("FINAL VARIABLE DEFINED INSIDE METHOD, SCORER NAME IS : - " + mictd.getScorerName());
                        ;
            }
}

Result:-

ACCESSING PRIVATE VARIABLE, TOTAL SCORE MADE BY SCORER IS : - 175
ACCESSING CLASS LEVEL STATIC VARIABLE :- MYSELF STATIC VARIABLE
ACCESSING LOCAL INNER CLASS METHOD, TOTAL BOUNDRY HITTED INCLUDING FOUR AND SIX IS : - TWENTY SEVEN
NUMBER OF SINGLES TAKEN BY SCORER IS : - TWENTY
FINAL VARIABLE DEFINED INSIDE METHOD, SCORER NAME IS : - CHRIS GAYLE


  • Member Inner class: - When a class is declared inside a class but outside a method then it is known as Member inner class. We can use public, private, protected and default access specifiers with Member inner class. For the instantiation of member inner class, we must have an instance of the outer class.

Example of Member Inner class
 
package com.gaurav.corejava.innerclass;

public class MemberInnerClassTestDemo {

            private String GLUCOSE_FORMULA = "C6H12O6";
            public static int number = 22;

            /** DECLARING A MEMBER INNER CLASS */
            class MemberInnerClass {
                        private final int OXYGEN_ATOMIC_NUMBER = 8;
                        String elementName = "UNIDENTIFIED ELEMENT";

                        public String getElementName(int num) {
                                    System.out.println("GLUCOSE FORMULA IS :- " + GLUCOSE_FORMULA);
                                    System.out.println("OXYGEN ATOMIC NUMBER IS :- "
                                                            + OXYGEN_ATOMIC_NUMBER);
                                    if (num + number == 100)
                                                elementName = "FERMIUM";
                                    else if (num == 22)
                                                elementName = "TITANIUM";
                                    return elementName;
                        }

            }

            public static void main(String args[]) {
                        MemberInnerClassTestDemo mictd = new MemberInnerClassTestDemo();
                        MemberInnerClassTestDemo.MemberInnerClass mic = mictd.new MemberInnerClass();
                        System.out
                                                .println("ACCESSING MEMBER INNER CLASS METHOD, THE ELEMENT NAME HAVING ATOMIC NUMBER 100 IS :- "
                                                                        + mic.getElementName(78));
                        // SECOND APPROACH TO CREATE AN INSTANCE OF MEMBER INNER CLASS.
                        MemberInnerClassTestDemo.MemberInnerClass mic2 = (new MemberInnerClassTestDemo()).new MemberInnerClass();
                        System.out.println("*****************************************");
                        System.out
                                                .println("SECOND TIME ACCESSING MEMBER INNER CLASS METHOD, THE ELEMENT NAME HAVING ATOMIC NUMBER "
                                                                        + number + " IS :- " + mic2.getElementName(22));

            }
}

Result:-

GLUCOSE FORMULA IS :- C6H12O6
OXYGEN ATOMIC NUMBER IS :- 8
ACCESSING MEMBER INNER CLASS METHOD, THE ELEMENT NAME HAVING ATOMIC NUMBER 100 IS :- FERMIUM
*****************************************
GLUCOSE FORMULA IS :- C6H12O6
OXYGEN ATOMIC NUMBER IS :- 8
SECOND TIME ACCESSING MEMBER INNER CLASS METHOD, THE ELEMENT NAME HAVING ATOMIC NUMBER 22 IS :- TITANIUM


  • Anonymouse Inner class: - If an inner class is defined which does not have any name than that inner class is called as annoymous inner class. The annoymous inner class is a sub class to parent class but it does not have any name. Anonymous inner class type must be either a subclass of the named type or an implementer of the named interface. An anonymous inner class can extend one class or implement only one interface. As the name of the constructor must be similar to the name of the class and in this case this class is not having name, So an anonymous inner class cannot have constructors.
Example of Anonymouse Inner class


package com.gaurav.corejava.innerclass;

interface TestInterface {
                String readStringValue();
}

class AnonymousInnerClass {
                public TestInterface testFunction(final String strTestParameterValue) {
                                // THIS IS DEMO EXAMPLE OF ANONYMOUS INNER CLASS.
                                return new TestInterface() {

                                                private String strValue = strTestParameterValue;

                                                public String readStringValue() {
                                                                System.out.println("\nINSIDE THE READSTRINGVALUE() METHOD");
                                                                return strValue;
                                                }
                                };
                }

                public static void main(String[] args) {
                                System.out.println("\n************* ANONYMOUS INNER CLASS DEMO EXAMPLES ***********************");
                                AnonymousInnerClass aic = new AnonymousInnerClass();
                                TestInterface testInterface = aic
                                                                .testFunction("IT'S ANONYMOUS CLASS DEMONSTRATION EXAMPLE");
                                System.out.println("STRING VARIABLE VALUE IS - "
                                                                + testInterface.readStringValue());
                }
}

Result:-

************* ANONYMOUS INNER CLASS DEMO EXAMPLES ***********************

INSIDE THE READSTRINGVALUE() METHOD
STRING VARIABLE VALUE IS - IT'S ANONYMOUS CLASS DEMONSTRATION EXAMPLE

No comments:

Post a Comment