Java Interface Example

Category: Java   Tags: Java, Java Basic, Java Interface

A Java interface contains just method declaration not the implementation. It is the job of class that implements this interface, implement all methods. Each class is free to determine the details of its own implementation. It has below syntax:

                          access-modifier interface InterfaceName {
                            return-type method-name1(parameter-list);
                            return-type method-name2(parameter-list);
                            ..
                            ..
                            return-type method-nameN(parameter-list);

                            type varname1 = value;
                            ..
                            ..
                            type varnameN = value;
                          }
                        

If no access modifier is specified, then default access is applied, and the interface is only available to other members of the same package. When it is declared as public, the interface is accessible from everywhere. If the access is public, the interface must be the only public interface declared in the file, and the file must have the same name as the interface.

All methods and variables are implicitly public. All interface variables are implicitly final and static and they cannot be changed by the implementing class. They must also be initialized.

Interface support dynamic method resolution at run time. If a class method want want to call another class method, both classes need to be present at compile time.

Once you define an interface, it can be implemented by one or more classes using implements. A class that implements an interface can have its own methods and variables also not just that defined in interface. Here is a simple example of an interface:

Shape.java

                            package com.tutorial.javabasic;

                            public interface Shape {
                                void draw();
                                double area();
                            }
                        

Rectangle.java

                            package com.tutorial.javabasic;

                            public class Rectangle implements Shape {

                                private double width;
                                private double height;

                                Rectangle(double w, double h) {
                                    width = w;
                                    height = h;
                                }

                                @Override
                                public void draw() {
                                    System.out.println("Draw rectangle.");
                                }

                                @Override
                                public double area() {
                                    return width * height;
                                }

                            }
                        

Circle.java

                            package com.tutorial.javabasic;

                            public class Circle implements Shape {

                                private int radius;

                                Circle(int r) {
                                    radius = r;
                                }

                                @Override
                                public void draw() {
                                    System.out.println("Draw Circle");
                                }

                                @Override
                                public double area() {
                                    return Math.PI * radius * radius;
                                }
                            }
                        

Main.java

                            package com.tutorial.javabasic;

                            public class Main {

                                public static void main(String s[]) {
                                    Shape shape = new Rectangle(10, 20);
                                    double rectangleArea = shape.area();
                                    shape.draw();
                                    System.out.println("Rectangle area: " + rectangleArea);

                                    shape = new Circle(10);
                                    double circleArea = shape.area();
                                    shape.draw();
                                    System.out.println("Circle area: " + circleArea);
                                }
                            }
                        

Output:

                            Draw rectangle.
                            Rectangle area: 200.0
                            Draw Circle
                            Circle area: 314.1592653589793
                        

Lets discuss some interesting things happening here:

                            Shape shape = new Rectangle(10, 20);
                            double rectangleArea = shape.area();
                        

Here shape is referring to Rectangle class and therefore calling the Rectangle version of area().

                            shape = new Circle(10);
                            double circleArea = shape.area();
                        

Here the same shape is referring to Circle class and calling the Circle version of area(). This is how interface support dynamic method resolution at run time.

Default Interface Methods

Beginning with JDK 8, an interface can have a default method implementation. A default method lets you define a default implementation for an interface method. A default method has below syntax:

                              access-modifier interface InterfaceName {
                                default return-type method-name1(parameter-list);
                              }
                            

So basically a default method will be prefixed with default. Here is one example:

Main.java

                            package com.tutorial.javabasic;

                            interface Printable {
                                default void print() {
                                    System.out.println("Print using default method.");
                                }
                            }

                            class A implements Printable {
                                @Override
                                public void print() {
                                    System.out.println("Print using A's method.");
                                }
                            }

                            class B implements Printable {

                            }

                            public class Main {

                                public static void main(String s[]) {
                                    Printable printable = new A();
                                    printable.print();

                                    printable = new B();
                                    /*
                                     It will use default implementation of print() method.0
                                    */
                                    printable.print();
                                }
                            }
                        

Output:

                            Print using A's method.
                            Print using default method.
                        

Here class B doesn't have any implementation of print method therefore it use the default implementation.

Why Default Methods?

Prior to JDK 8, a class using an interface had to implement all methods declared inside the interface. The problem was that if a new method is added to interface, the existing class that uses this interface will break.

Now you can have a default implementation of a method inside interface only. So if a class do not implement that method, the default version will be called.