DEV Community

Dallington Asingwire
Dallington Asingwire

Posted on • Updated on

Inner or nested classes in java

An inner class is a class that is declared inside a class or interface. Inner classes are used to logically group classes or interfaces in one place in order to improve readability and maintainability.
Syntax of inner class

class X1{
// code
  class X2{
      // code
    }
}
Enter fullscreen mode Exit fullscreen mode

Advantages of using inner classes

  1. Because inner classes logically group classes and interfaces in one place only, they improve readability and maintainability.
  2. minimises coding efforts since there is less code to write thus facilitating code optimisation.
  3. Inner classes are a representation of a particular type of relationship in that an inner class can access all the members(data members and methods) of an outer class including one declared private.

Why need an inner class?
There might be a program where a class must not be accessed by other class so in that case, you include it in another class.

Types of inner classes
There are 4 types of nested/inner classes i.e member(nested inner class), static member(static nested class), anonymous inner class and local inner class.
A) Static member inner classes
A static member inner class is an inner class which is declared static.
Syntax for a static inner class

  class MainClass {
    // code
    static class StaticInnerClass{
     // code
    }
}
Enter fullscreen mode Exit fullscreen mode

In the above code snippet, StaticInnerClass is a static inner class.
This class can't refer directly to their instance variables or methods defined in its enclosing class since they use them only by an object reference. They are accessed by the use of class name.
Note: Syntax for creating an object of a static inner class

MainClass.StaticInnerClass objectname 
= new MainClass.StaticInnerClass();
Enter fullscreen mode Exit fullscreen mode

Example:

 class A{
  static String parent_name = "A";
  static class B{
    void whoami(){
      System.out.print("I am static inner class B
          and my parent class is"+parent_name);
     }
  }
 public static void main(String[] args)  
      {  
        A.B obj = new A.B();  
        obj.whoami();  
      }
}
Enter fullscreen mode Exit fullscreen mode

Output

I am static inner class B and my parent class is A
Enter fullscreen mode Exit fullscreen mode

In the above example, B is a static inner class and an instance method like whoami() is accessed by using class name B.

B. Member inner class
A member inner class is a class created within a class and outside a method. A member inner class is non-static.
A member inner class refers directly to its instance variables or methods defined in its enclosing class. Also, because an inner class is associated with an instance, it cannot define any static members itself.
Syntax for a member inner class

class MainClass
  {
    // code
    class InnerClass
      {
        // code
      }
  }
Enter fullscreen mode Exit fullscreen mode

Note: Syntax for creating an object of a non-static member inner class

MainClass m = new MainClass();
MainClass.InnerClass innerObj = m.new InnerClass();
Enter fullscreen mode Exit fullscreen mode

Example

class X{
     static String parent_name ="X";
     class Y{
       void message(){
        System.out.println("Hey, I am an non-static inner 
             class Y and my parent class is "+parent_name);
     } 
    }

public static void main(String[] args)  
      {  
        X x = new X();
        X.Y innerObj = x.new Y();
        innerObj.message();  
      }
}

Enter fullscreen mode Exit fullscreen mode

Output

Hey, I am an non-static inner class Y and my parent class is X
Enter fullscreen mode Exit fullscreen mode

C. Anonymous inner class
Anonymous inner class is one that is created for implementing an interface or extending a class. Thereafter, anonymous class must implement an interface or extend an abstract class but you don't use keywords extend or implement to create anonymous class.
Syntax for creating anonymous class

new interface-or-class-name{
  // code
}
Enter fullscreen mode Exit fullscreen mode

Example:

import java.util.Random;

public class AnonymousClassExample {

    interface Food{
        public void choose();
        public void whichFood();
    }

    public void eat() {

        // Anonymous class
  Food birdsFoodPreference = new Food() {
        public void choose() {
            whichFood();
        }
        public void whichFood() {
     String [] foodItems = {"Insects", "Maize", "G.nuts"};
      System.out.println("Birds like eating 
                         "+getRandomFoodChoice(foodItems));
    }
    };

    // Anonymous class
    Food MansFoodPreference = new Food() {
        public void choose() {
            whichFood();
        }
        public void whichFood() {
   String [] foodItems = {"Meat", "Posho", "Rice"};
    System.out.println("Man likes eating 
                   "+getRandomFoodChoice(foodItems));
        }
    };

    birdsFoodPreference.choose();
    MansFoodPreference.choose();

    }

    public static void main(String[] args) {
AnonymousClassExample app = new AnonymousClassExample();
app.eat();

    }

    public static String getRandomFoodChoice(String[] array) {
        int rnd = new Random().nextInt(array.length);
        return array[rnd];
    }

}
Enter fullscreen mode Exit fullscreen mode

Output

Birds like eating Insects
Man likes eating Posho
Enter fullscreen mode Exit fullscreen mode

Key facts about anonymous inner classes

  1. Anonymous class cannot have a constructor. Thus, you cannot pass parameters to an anonymous class when you instantiate it.
  2. Anonymous class can access any variables visible to the block within which anonymous class is declared, including local variables.
  3. Anonymous class can also access methods of a class that contains it.

D. Local inner class
A local class is a class that is defined in a block, which is a group of zero or more statements between balanced braces. You typically find local classes defined in the body of a method.

import java.util.*;
public class Bank {

    public static void getTotalPayable(String bank, 
              double principal, int years) {

        // local class named Interest
         class Interest{
           double bank_interest_rate = 0.0;

               Interest(String bank){
                 switch (bank) {
                   case "Centenary":
                      bank_interest_rate = 3.2;
                      break;
                   case "Stanbic":
                         bank_interest_rate = 2.8;
                     break;
                   case "Equity":
                         bank_interest_rate = 3.15;
                     break;
                       default:
                         bank_interest_rate = 1.5;
    }

    }
// method in local class that returns interest
    public double getInterestRate() {
     return bank_interest_rate;
    }

 }

Interest obj = new Interest(bank);
double amount = Math.round(principal*
               (1 + (obj.getInterestRate()*years)));

System.out.println("The total amount payable
 for principal "+principal+" after
 "+years+" years in "+bank+" bank
 whose interest is "+obj.getInterestRate()+"
 is "+amount);

 }


    public static void main(String[] args) {
        double amt = 100000;
        int years = 3;
        getTotalPayable("Centenary", amt, years);
        getTotalPayable("Stanbic", amt, years);
        getTotalPayable("Equity", amt, years);

    }

}
Enter fullscreen mode Exit fullscreen mode

Output

The total amount payable for principal 100000.0 after 3 years in Centenary bank whose interest is 3.2 is 1060000.0
The total amount payable for principal 100000.0 after 3 years in Stanbic bank whose interest is 2.8 is 940000.0
The total amount payable for principal 100000.0 after 3 years in Equity bank whose interest is 3.15 is 1045000.0
Enter fullscreen mode Exit fullscreen mode

So that's the concept of inner classes in java, thank you to taking time to read through this post. See you in the next one!

Top comments (0)