Tame the Beast of Inner Classes

An Inner Class or Nested Class is a class defined within another Class. Inner classes were introduced in the version 1.1 of Java (in the year 1997). Interfaces can also be defined as Inner Interfaces.

The enclosing class is called the Outer class and the nested class is called the Inner class.

Demonstration of Inner Class

Inner Class

Why do we use Inner Class?

As soon as an application enters the development phase, the developer needs to maintain the code. He needs to write the code in such a way that it would be easy to understand and interpret by someone else who has never worked on that application. This is where inner classes come handy. Inner classes are used to group classes or interfaces together so as to make the program more readable and maintainable.

Think of inner classes as a Refrigerator. Cooling inside the refrigerator reaches everything within it. Similarly, the data members and functions of the outer class are accessible/visible in the inner classes as well.

Syntax for creating an object of a non-local inner class:

Step 1 : Create object of outer class

Step 2 : Use the object of outer class to create an object of inner class

 Why use Inner Classes

The main reason for using Inner classes are useful is because it provides better encapsulation and cleaner code.

When we need to access private data members of a class, we can do so by using its getters and setters. If the private members are to be accessed only in one separate class, it can become very difficult to maintain such an application.

Inner Classes for Encapsulation

Let’s have a look at this through an example:

These are hypothetical classes. A “Chat_Application” class holds a private object of another class “Message”. Both the methods are able to access the private object. This was version 1.

In version 2, we decided to add two new features:

  • Process emoticons while reading the message form the chat box and convert them into characters corresponding to their display icons
  • Encrypt the entire string before sending it to the server

Unfortunately, our team decided that we didn’t have time to write our own modules for encryption and emoticon processing. So, we decided to use external libraries for both purposes.

The emoticon processing library provides an abstract class “Emoji” having the parseEmoji() method. To use it, we must extend the class. The encryption library provides another abstract class “Encryption” having the encryptMessage() method. In both cases, the required methods are defined in abstract classes. So, we cannot create their objects, both classes need to be extended.

Can we make the Chat_Application class extend two classes? Remember that this kind of multiple inheritance is not allowed in Java.

So, we decide that we will make two separate classes as follows:

As we can see, these two classes are much closely related than we previously thought. Of course, the “Secure_Sending” class could use the getter/setter methods of “Chat_Application” class to access the “message” object. But if the “Message” class gets changed in future, then you will have dependencies in two different classes.

Keep in mind that:

Only one class i.e. “Secure_Sending” is accessing the private data of “Chat_Application” class. Moreover, the object of Secure_Sending will not be able to function without the object of “Chat_Application”; both have a close relationship.

This is where Inner classes come into picture and help us make our code manageable. Now, we can combine “Chat_Application” and “Secure_Sending” classes as follows:

From the above code snippets, we can deduce the following.

Benefits of using Inner Classes

  1. Two different classes are merged together to form one single class with the help of inner classes.
  2. The length of the code has reduced slightly.
  3. Since both classes are so strongly dependent on each other, we will have to ensure that an object of “Secure_Sending” class must be created only after an object of “Chat_Application” class.

An inner class object has a special relationship with the outer class object; it can access even the private members directly.

Inner Classes can be Public, Private, Default or Protected. But Outer Classes CANNOT be Private or Protected. They also cannot be static.

Types of Inner Classes

Next topic in this post brings us to types of inner classes supported in Java. There are two basic categories of Inner classes:

Types of Inner Classes

Types of Inner Classes

 

  1. Method-local Inner Classes: These are inner classes written inside a method of the outer class. Object creation of these inner class is restricted only to the enclosing method. not rest of the the outer class. These inner classes can also have all 4 access specifiers – public, private, default, and protected.
  2. Non-Local Inner Classes: When an inner class is declared directly inside the inner class (not in any method), it is called a non-local inner class. Its object creation totally depends on the visibility of the class. Only non-private, non-local classes can be accessed outside the outer class for object creation.

Static Nested Class

Static Nested classes are declared with the keyword static. Such classes act just like static methods in terms of access restrictions.

A static inner class will not be able to access private members of the outer class. It can access only static members.

Why should one opt for a static inner class when it cannot access private data members of the outer class?

Static nested class actually does not provide any advantage over the non-static nested class. It is considered a good design practice to club two classes together even if they don’t have such a close relation. Of course, the rest of the code will not be able to access the inner class.

There is also a fourth type of class which is written inside a method. It is called as Anonymous Inner Class. It has a totally different syntax and functionality, so will discuss that in another post.

(Thanks to my co-writer Ismail Memon for contributing to this article!)

No Responses

Leave a Reply