Sunday, July 28, 2013

Nested Interface in Java

As with classes, you can nest interfaces inside an outer class or another interface. The dynamics are similar to nested classes. However, keep in mind that the classes that ultimately implement these nested interfaces don't have the special access to the class members that a nested class does; instead,they behave just like normally declared classes.

An interface which is declared within another interface or class is known as nested interface.It is used to group related interfaces so that its easy to main. Nested interface must be referred by the outer interface or class, it can not be accessed directly.
Example :
Nested interface inside a class

class java {
    public interface latte {
        /* funtion name */
    }  
}


Nested interface inside a interface

interface java {
    public interface latte {
        /* funtion name */
    }   
}


Point to remember about nested interface.

  1. Nested interface must be public if is declared inside the interface
  2. It can have any access modifier if declared inside the class.
  3. a nested interface is automatically "static"
If a nested interface is declared like this

class java {
    public static interface latte {
        /* funtion name */
    }   
}


The static keyword in the this example is redundant and can be removed with no effect on semantics. Same like for "public" on interface methods and "public final" on interface fields - the modifiers are redundant.
An inner interface has to be static in order to be accessed. The interface isn't associated with instances of the class, but with the class itself, so it would be accessed with java.latte, like so:

public class Baz implements java.latte {
   ...

}


To better understand nested interface look at the Map.Entry static interface declared inside Map interface.
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Map.html
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Map.Entry.html


Example of Map.Entry interface


HashMap<String, String> map = new HashMap<String, String>();
for (Map.Entry<String, String> entry : map.entrySet())
{
    System.out.println(entry.getKey() + "/" + entry.getValue());

}


Entry is subinterface of Map ie accessed by Map.Entry


Nested Interfaces in Classes

The syntax for nested interfaces is the same as nested classes, but the results are quite different. Since you are defining only the interface and not the implementation, the user of the interface is free to implement the class any way he wants. A good example of a nested interface implementation is with a special collection


public class Inventory {
   public HashSet items;

   public Set getValues( ) {
      return Collections.unmodifiableSet(items);
   }

   public void addItem(final InventoryItem item) {
      items.add(item);
   }

   public Iterator iterator( ) {
      return items.iterator( );
   }

   public void removeElement(final InventoryItem item) {
      items.remove(item);
   }

   public static interface InventoryItem {
      public String getSKU( );
   }
}

In this example, the special collection named Inventory will contain only objects that implement the InventoryIteminterface (and therefore define the method getSKU( )). Furthermore, since you don't want to tie down the inventory items to a particular superclass, you make an interface for the inventory items, which allows the user to implement that interface as he sees fit.

There are only a few good reasons why you should use inner interfaces. One is to model a composition relationship without restricting the implementation of the composed object. In this case, you would need an inner interface to model the compositional relationship and to let the user of the interface decide on the implementation.

Nested interfaces are useful on rare occasions, but most of the time you can achieve the same results simply by declaring the interface in its own file.


Nested Interfaces in Interfaces

It is also possible to nest interfaces within other interfaces, although this is rarely done. The syntax is the same as with nested classes. Although using interfaces nested in other interfaces is less crazy than nesting classes within an interface, it is still pretty weird.

Essentially, when you nest an interface inside another interface, you are describing a compositional relationship among interfaces. Conceptually, it is a rather strange thing to do

Demo :

Map.java

public interface Map {
 interface Entry{
  void getKey();
  void getValue();
 }

}


JavaLatte.java

public class JavaLatte implements Map.Entry {
 @Override
 public void getKey() {
  System.out.println("This is key");
 }
 @Override
 public void getValue() {
  System.out.println("This is value");
 }

  public static void main(String myblog[]){
  Map.Entry entry=new JavaLatte(); //upcasting
  entry.getKey();
  entry.getValue();
 }

}


Can we create a class inside the interface?
Yes, OfCourse. If we define a class inside the interface, java compilter create a static nested class.
interface javalatte{
class TEST{}
}

Where we can use nested interface?
As you seen above, that with the help of nested interface you can get the key and value in a single loop.
According to me, there may a case where you need to get many values in a loop instead of getting one by one.

For instance, I need to get customer name, customer address and his bank balance in a loop. See the below example:

public class test1 {

 public static void main(String myblog[]){
  Map.Entry entry=new Bank(); //upcasting
  entry.getUserAddress();
  entry.getUserName();
  entry.getBalance();
 }

}

class Bank implements Map.Entry{

 public void getUserName() {
  System.out.println("This is pardeep");
 }

 public void getUserAddress() {
  System.out.println("India");
 }
 public void getBalance() {
  System.out.println("30m $");

 }
}

interface Map {
 interface Entry{
  void getUserAddress();
  void getUserName();
  void getBalance();
 }

}

Sample Output:
India
This is pardeep
30m $





Thanks for reading the post !
Please share or comment on this as this encourage me to write more :) 

1 comment: