Interface in Java with programming Examples
Interface in Java
In Java, there are not only classes but also interfaces. These are introduced with the keyword interface instead of the keyword class. Interface in java, like classes, should each be stored in a separate Java file. In terms of structure, interfaces are very similar to a class; they are almost comparable to abstract classes that only contain method declarations. The only difference to a class is that an interface in java has no implementations, just method headers, and constants.
Let’s take a look at the syntax of an interface in java
1 2 3 4 5 |
modifier interface MyInterface { final modifier data type variable = value ; modifier data type method ( ) ; } |
The header of an interface in java is structured like that of a class, except that the keyword class is replaced by the interface in java. Only constants and method names can be in the body of the interface.
Among other things, interfaces are used to separate the specification of classes from their implementation. But you can also use interfaces to protect the actual implementation from third parties. Interfaces and the methods they contain can therefore also be used as communication interfaces since the transfer parameters to be expected and the return value is defined by the method header.
Like classes, an interface in java can also have an inheritance hierarchy. The same rules apply there as for classes (single inheritance, visibility, etc.).
But since we also want to use interface in java, we have to integrate them into a class somehow. This is done using the implements keyword. The following example shows how the MyInterface interface above is included in a class.
1 2 3 4 |
modifier class class extends superclass implements MyInterface { // statements } |
We can easily extend the normal structure of a class with the new interface by including our interface MyInterface in front of the class body with the keyword implements. Integrating an interface can take place parallel to inheritance. You can include any number of interfaces in a class, the interface names are then simply separated by a comma in the class header. This is often used to simulate a kind of multiple inheritances in Java since this is otherwise not directly possible.
Let’s look directly at a concrete example.
Example: how to use Interface in java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
interface PrintMessage { /* Methods to be implemented by a PrintMessage*/ void Message(); } /* Our class Test which encapsulates the PrintMessage interface */ public class Test implements PrintMessage { /* Implementation of the Message method from the PrintMessage interface */ public void Message( ) { System.out.println("Hello Programming digest"); } // main method public static void main(String []args ) { Test obj = new Test (); obj.Message(); } } |
In the example above, we have created an interface called PrintMessage which will be included in the Test class. The Test class must then implement the method declarations from the interface.
Output:
Java multiple interfaces in a class
Since we can only simulate indirect multiple inheritances in Java by including multiple interfaces, we now want to deal with this topic in more detail.
Integrating multiple interfaces in java is not always possible. For example, the same method may be declared in two interfaces and the method declarations differ only in the return value. In this case, it is not possible to integrate these two interfaces at the same time. If the two method declarations are the same, both interfaces can be integrated, but the method then only exists once in the class.
Constants from different interfaces can have the same name but a different value. However, this should be avoided. However, you can then access the respective constant by specifying the interface name.
Let’s take a look at an example.
Example: how to use multiple interfaces in a class in java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
// Interface Section1 interface Section1 { /* Constants VAR1 and VAR2 */ public static final int VAR1 = 20 ; public static final int VAR2 = 30 ; /* method setValue with a transfer parameter of data type int */ public void setValue(int value ); } // Interface Section2 interface Section2 { /* Constants VAR1 and VAR3 (VAR1 is already declared in the Interface Section1) */ public static final int VAR1 = 40; public static final int VAR3 = 50; /* SetValue method with a transfer parameter of data type int (identical to the method from Section1) */ public void setValue( int value ); } /* Start class Test, which includes our interfaces Section1 and Section2*/ public class Test implements Section1,Section2{ /* locally defined constant VAR1 */ private static final int VAR1 = 80 ; /* implemented method from the Interface Section1 and Section2 */ public void setValue ( int value ) { /* Instructions */ } // main method public static void main(String []args ) { System.out.println(VAR1) ; System.out.println(VAR2) ; System.out.println(VAR3) ; System.out.println(Section1.VAR1); System.out.println(Section2.VAR1) ; } } |
In the above example, we have two interfaces Section1 and Section2. Both have two constants and a method. This is followed by the start class Test, which integrates our two interfaces Section1 and Section2. The method from the interfaces Section1 and Section2 is not critical because it is declared the same in both classes. In addition, the interfaces each have a constant with the same name, VAR1, but a different value, and a completely different constant, VAR2 and VAR3.
Our start class Test now implements both interfaces. The Test class also has its own constant called VAR1. In total, there are three times the constant VAR1, each with a different value. The setValue method is implemented in the Test class, ie we give it a method body at this point.
In the main method, we now output the constants.
Output:
Special interface in java
In Java, there are already some predefined interfaces that can be integrated for specific tasks. In the following, we want to look at some more special interfaces. Interfaces are often used to deal with or react to special events. A large part of interfaces is used in the area of ​​GUI (Graphical User Interface) development. Graphic surfaces have to react to inputs, for example, there are special interfaces for this. We will go into more detail about these special interfaces later in the articles on GUI programming (event handling).
Cloneable Interface in java
A special interface in java is the Cloneable interface. This serves to create an exact copy of an object. Normally one would think that an assignment also creates an exact copy of an object. However, this is only the case for simple data types. In the case of objects, however, when an assignment is made, there is only a reference to the memory area in which the object is located. To illustrate this referencing, let’s take a look at the following example.
Example1: how to use Cloneable interface in java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
class Copy { // attribute x int x ; // constructor for setting the attribute public Copy( int x ) { this.x = x ; } // Method for outputting the attribute public void print ( ) { System.out.println( " x = " + x ) ; } } /* Start class Test to test our class Copy with the assignment. */ public class Test { // main method public static void main ( String [ ] args ) { /* creating an object with the new operator */ Copy ref1 = new Copy( 10) ; /* The variable ref2 is assigned the content of ref1 */ Copy ref2 = ref1 ; /* Call the print method */ ref1.print( ); ref2.print( ); /* Attribute x of the object referenced by ref1 is assigned the value 20 */ ref1.x = 20 ; /* Call the print method again */ ref1.print( ); ref2.print( ); } } |
Output:
Program Explanation:
In the main method, we first create an object of the copy class and assign it to the variable ref1. Right after that, we assign the value of ref1 to the variable ref2. If we now look at the output, we see that the first two outputs are identical. This is also not surprising since the first two outputs occurred directly after the assignment (ref2=ref1). The other two editions are more surprising. We recently changed the x attribute of ref1. Therefore, one might have expected that the output from both objects ref1 and ref2 are different. But since we already said before this example that an assignment to objects does not create a copy of the first object, but only refers to it, this output is only logical, since we are referencing the same object via both variables.
Please see the following pictures for illustration.
In the above image, you can see the assignment from our object ref1 to ref2. Both “point” to the same object. This type of assignment also happens with method calls that have objects as transfer parameters. This allows you to implement multiple return values ​​in a method by changing the attributes of the object. However, this is not always desired and therefore one must first consider whether one actually wants to change the existing object.
if we really want to copy the object, we have to clone it. The cloning is shown in the above image. Here each variable points to its own object after the cloning process. At this point, a change does not affect the other variable.
We now extend our copy class and implement the Cloneable interface there.
Example2: how to implement the Cloneable interface in java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
/* Our class copy implements the Cloneable interface here */ class copy implements Cloneable { // attribute x int x ; // constructor for setting the attribute public copy ( int x ) { this.x = x ; } // Method for outputting the attribute public void print( ) { System.out.println ( "x = " + x ) ; } /* Implemented method from the Cloneable interface */ /* This method can throw a CloneNotSupportedException */ public Object clone( ) throws CloneNotSupportedException { /* Here the clone method of the superclass (in this case Object) is called. */ return super.clone( ) ; } } /* Start class CopyTest to test our class Copy with the clone method. */ public class Test { // main method public static void main ( String [ ] args ) { /* Creation of an object with the new operator and the constructor with the value 10 */ copy ref1 = new copy(10) ; // initialize ref2 with null copy ref2 = null ; try { /* Copy attempt from object ref1 to ref2 */ /* Since the clone method returns the data type Object, we need to do a typecast to our copy class */ ref2 =(copy)ref1.clone ( ) ; } catch(CloneNotSupportedException ex ) { /* catch the exception CloneNotSupportedException */ System.out.println("Copying of this object is not supported" ) ; } /* Call the print method of both objects */ ref1.print( ) ; ref2.print( ) ; /* Attribute x of the object referenced by ref1 is assigned the value 20 */ ref1.x = 20 ; /* Call the print method of both objects again */ ref1.print( ) ; ref2.print( ) ; } } |
Output:
Program explanation:
We have now included the Cloneable interface in our Copy class. For this reason, we also implement the clone method. At this point in the clone method, we simply call the clone method of the superclass, namely Object. Then the cloned object is returned or the exception CloneNotSupportedException is thrown. Now if we look at the output, we see that our cloned object has not changed after we made the change to the object referenced by ref1. Since the clone method can throw an exception, we also need to add error handling and catch that exception.
Experienced developers can see from the source code that the error handling has not been solved well. Two other exceptions that could not have been caught or detected by simple inspection may occur. The first additional exception that should have been caught in another catch block would be the TypeCastException that can occur during type conversion from Object to Copy. The second additional exception that can occur would be the NullPointerException. If an exception occurs in the try block, ref2 remains at the value null. With the method call ref2.print() the NullPointerExceptionthrown.
You can also implement the clone method yourself by creating a new object of the class to be copied with the new operator and assigning the existing attributes, provided they are simply data types, to the new object and then returning the newly created object. Depending on which superclasses exist, you may have to implement the method yourself and not call super.clone(). Let’s now look at a separate method clone for the above class Copy, without including the superclass.
1 2 3 4 5 |
public Object clone( ) throws CloneNotSupportedException { return new copy(this.x ) ; } |
This is a very simple example, but basically calling the super.clone() method does nothing else. With more complex objects, of course, more attributes have to be “cloned”, so the method would contain a few more statements.
Java interface as a data type:
Interface in java can also be used as a data type. It should be noted, however, that no object can be created from an interface using the new operator. An instance of an interface can only be created via assignments, by assigning an object of a class that implements the interface to a reference variable that has the interface to the data type.
This also makes it possible, as shown in the following example, to store objects of different classes in an array.
Let’s look at a small example first.
Example: how to use java interface as a data type:Â
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
interface myInterface { public int getX( ); public void setX(int i ); } class anyName1 implements myInterface { private int x ; public int getX ( ) { return x ; } public void setX ( int i ) { x = i ; } } class anyName2 implements myInterface { private int x,y ; public int getX ( ) { return x ; } public void setX ( int i ) { x = i ; } public int getY ( ) { return y ; } public void setY ( int i ) { y = i ; } } // Our starting class for testing public class Test { public static void main ( String [ ] args ) { /* Assignment of a anyName1 object to the variable Object1 with the data type myInterface */ myInterface Object1 = new anyName1( ) ; /* Assignment of a anyName2 object to the variable object2 with the data type myInterface */ myInterface Object2 = new anyName2( ) ; /* Creation of an array with the data type myInterface */ myInterface Arr [ ] = new myInterface[ 2 ] ; /* Calling the setX method from the interface */ Object1.setX ( 60 ) ; Object2.setX ( 20 ) ; /* Object1 and object2 are entered in the array */ Arr[ 0 ] = Object1 ; Arr[ 1 ] = Object2 ; /* for loop for outputting the x values */ for ( int i = 0 ; i < Arr. length ; i ++ ) { /* Calling the getX method of the interface */ System.out.println ( "Interface object returns the value for x: " + Arr [ i ].getX( ) ) ; } } } |
Output:
Program Explanation:
At this point, I used anyName1 and anyName2 classes and the myInterface interface. The anyName2  also integrates the myInterface interface, and also implements its methods. This class also has an attribute y and the associated get or set method.
In order for us to test this, we need a starting class Test. There we declare two variables Object1 and Object2, which have the myInterface data type interface, and assign an object of the anyName1 type to the first and an instance of the anyName2 class to the second. We then declare an array whose elements should be of the myInterface type. We then call the setX method from the interface for each object. Then we move the Objects into the array and let us output the x-values in the for loop via the method getX declared in the interface.
You can see that the anName2 class has one more attribute and two more methods. However, these are no longer accessible after the assignment to the variable Object2, since the object only has the methods of the interface. It would first have to be typecast to the anyName2 class for access to be possible.
As you can see from this example, interface in java can also be used as data types, but it should be noted that only the methods declared in the interface can be accessed. Access to the methods additionally implemented in the original class is not possible.