Inner and Nested Classes in Java

Loading

In Java, inner classes and nested classes are used to logically group classes and interfaces within a single unit. They help in encapsulation and can lead to more readable and maintainable code. Let’s explore these concepts in detail:


1. Nested Classes

A nested class is a class defined within another class. There are two types of nested classes:

  1. Static Nested Classes
  2. Non-Static Nested Classes (Inner Classes)

2. Static Nested Classes

  • Declared with the static keyword.
  • Belongs to the outer class, not to instances of the outer class.
  • Can access only static members of the outer class.
  • Can be instantiated without an instance of the outer class.

Example:

public class OuterClass {
    static int outerStaticVar = 10;
    int outerInstanceVar = 20;

    static class StaticNestedClass {
        void display() {
            System.out.println("Outer static variable: " + outerStaticVar);
            // System.out.println("Outer instance variable: " + outerInstanceVar); // Error: Cannot access non-static members
        }
    }

    public static void main(String[] args) {
        OuterClass.StaticNestedClass nestedObj = new OuterClass.StaticNestedClass(); // No need for OuterClass instance
        nestedObj.display(); // Output: Outer static variable: 10
    }
}

3. Non-Static Nested Classes (Inner Classes)

  • Declared without the static keyword.
  • Belongs to an instance of the outer class.
  • Can access both static and non-static members of the outer class.
  • Requires an instance of the outer class to be instantiated.

Example:

public class OuterClass {
    int outerVar = 30;

    class InnerClass {
        void display() {
            System.out.println("Outer variable: " + outerVar); // Can access outer instance variable
        }
    }

    public static void main(String[] args) {
        OuterClass outerObj = new OuterClass();
        OuterClass.InnerClass innerObj = outerObj.new InnerClass(); // Requires OuterClass instance
        innerObj.display(); // Output: Outer variable: 30
    }
}

4. Types of Inner Classes

Inner classes can be further categorized into:

  1. Member Inner Class
  2. Local Inner Class
  3. Anonymous Inner Class

a. Member Inner Class

  • Defined at the member level of the outer class (like methods or variables).
  • Can access all members of the outer class.

Example:

public class OuterClass {
    private int outerVar = 40;

    class MemberInnerClass {
        void display() {
            System.out.println("Outer variable: " + outerVar);
        }
    }

    public static void main(String[] args) {
        OuterClass outerObj = new OuterClass();
        OuterClass.MemberInnerClass innerObj = outerObj.new MemberInnerClass();
        innerObj.display(); // Output: Outer variable: 40
    }
}

b. Local Inner Class

  • Defined inside a block, such as a method or a constructor.
  • Can only access final or effectively final local variables of the enclosing block.

Example:

public class OuterClass {
    void outerMethod() {
        final int localVar = 50;

        class LocalInnerClass {
            void display() {
                System.out.println("Local variable: " + localVar);
            }
        }

        LocalInnerClass innerObj = new LocalInnerClass();
        innerObj.display(); // Output: Local variable: 50
    }

    public static void main(String[] args) {
        OuterClass outerObj = new OuterClass();
        outerObj.outerMethod();
    }
}

c. Anonymous Inner Class

  • A class without a name, defined and instantiated in a single expression.
  • Commonly used for overriding methods of a class or interface.

Example:

interface Greeting {
    void greet();
}

public class OuterClass {
    public static void main(String[] args) {
        Greeting greeting = new Greeting() { // Anonymous inner class
            @Override
            public void greet() {
                System.out.println("Hello from anonymous inner class!");
            }
        };
        greeting.greet(); // Output: Hello from anonymous inner class!
    }
}

5. Key Differences Between Static and Non-Static Nested Classes

FeatureStatic Nested ClassNon-Static Nested Class (Inner Class)
DeclarationDeclared with static keywordDeclared without static keyword
Instance RequirementNo instance of outer class requiredRequires an instance of the outer class
Access to MembersCan access only static members of outer classCan access both static and non-static members of outer class
Memory UsageMore memory-efficientLess memory-efficient (tied to outer instance)

6. When to Use Inner and Nested Classes

  • Use static nested classes when:
  • The nested class doesn’t need access to instance variables of the outer class.
  • You want to group related classes logically.
  • Use inner classes when:
  • The nested class needs access to instance variables of the outer class.
  • You want to encapsulate functionality within the outer class.

7. Example Combining Inner and Nested Classes

public class OuterClass {
    private int outerVar = 60;
    static int outerStaticVar = 70;

    class InnerClass {
        void display() {
            System.out.println("Outer variable: " + outerVar);
        }
    }

    static class StaticNestedClass {
        void display() {
            System.out.println("Outer static variable: " + outerStaticVar);
        }
    }

    public static void main(String[] args) {
        // Inner class example
        OuterClass outerObj = new OuterClass();
        OuterClass.InnerClass innerObj = outerObj.new InnerClass();
        innerObj.display(); // Output: Outer variable: 60

        // Static nested class example
        OuterClass.StaticNestedClass nestedObj = new OuterClass.StaticNestedClass();
        nestedObj.display(); // Output: Outer static variable: 70
    }
}

By understanding inner and nested classes, you can design more modular and encapsulated Java programs!

Leave a Reply

Your email address will not be published. Required fields are marked *