Showing posts with label Java Interface introduction. Show all posts
Showing posts with label Java Interface introduction. Show all posts

Friday, 5 June 2015

Java Interface Examples

Example: This example is covered when discussing abstract classes. The example is modified such that instead of declaring Shape class as an abstract class it is declared as an interface. We cannot have any implementation in the Shape interface. The interface declares two methods, which must be implemented by all sub-classes of this interface. This would duplicate the code of
method calCost() in all the implementing classes.

interface Shape

{

double puCost = 100;

double area();

double calCost();

}

class Triangle implements Shape

{

double s1,s2,s3;

Triangle(double a, double b, double c)

{

}

public double calCost()

{

}

public double area()

{

s1 = a; s2 = b; s3 = c;

return puCost * area();

double s = (s1+s2+s3)/2;

return Math.sqrt(s*(s-s1)*(s-s2)*(s-s3));

}

}

class Rectangle implements Shape

{ double s1,s2;

Rectangle(double a, double b)

{

}

public double calCost()

{

}

public double area()

{

}

}

class Square implements Shape

{ double s;

Square(double a)

{ s = a;

}

public double calCost()

{

}

public double area()

{ return s * s;

s1 = a; s2 = b;

return puCost * area();

return s1 * s2;

return puCost * area();

}

}

class ShapeTest2

{ static public void main(String args[])

{ Shape s1 = new Triangle(3,4,5);

Shape s2 = new Rectangle(3,4);

Shape s3 = new Square(3);

System.out.println(s1.area());

System.out.println(s2.area());

System.out.println(s3.area());

System.out.println(s1.calCost());

System.out.println(s2.calCost());

System.out.println(s3.calCost());

}

}

Output:

6.0

12.0

9.0

600.0

1200.0

900.0

Example: This example improves the previous one by introducing additional sub-class AbstractShape between interface Shape and its sub-classes. This sub-class can contain the generic code for method calCost().

interface Shape

{
double area();

double calCost();

}

abstract class AbstractShape implements Shape

{ double puCost;

AbstractShape(double puCost)

{ this.puCost = puCost;

}

public double calCost()

{ return puCost * area();

}

}

class Triangle extends AbstractShape

{ double s1,s2,s3;

Triangle(double a, double b, double c, double puCost)

{ super(puCost);

}

public double area()

{ double s = (s1+s2+s3)/2;

}

}

class Rectangle extends AbstractShape

{ double s1,s2;

Rectangle(double a, double b, double puCost)

{ super(puCost);

}

public double area()

{ return s1 * s2;

}

}

class Square extends AbstractShape

{ double s;

Square(double a, double puCost)

{ super(puCost); 

}

public double area()

{ return s * s;

}

}

s1 = a; s2 = b; s3 = c;

return Math.sqrt(s*(s-s1)*(s-s2)*(s-s3));

s1 = a; s2 = b;

s = a;

class ShapeTest3

{ static public void main(String args[])

{ Shape s1 = new Triangle(3,4,5,10);

Shape s2 = new Rectangle(3,4,100);

Shape s3 = new Square(3,1000);

System.out.println(s1.area());

System.out.println(s2.area());

System.out.println(s3.area());

System.out.println(s1.calCost());

System.out.println(s2.calCost());

System.out.println(s3.calCost());

}

}

Output:
6.0
12.0
9.0
60.0
1200.0
9000.0

Example: The following example demonstrates that interface of the stack could be kept separate from its implementation by abstracting it using the interface StackInterface.

interface StackInterface

{ void push(int x);

int pop();

}

class Stack implements StackInterface

{ int top = -1; int a[] = new int[10];

public void push(int x)

{ if(top == 9)

{ System.out.println("Stack Full");

return;

}

top = top + 1; a[top] = x;

}

public int pop()

{ if(top ==  -1)

{ System.out.println("Stack Empty");

return -1; //assuming that -1 is not a valid data

}

int x = a[top]; top = top - 1; return x;

}

}

class StackTest

{ public static void main(String args[])

{ Stack st1=new Stack();

Stack st2=new Stack();

for(int i=1;i<5;i++)

{ st1.push(i);

}

for(int i=1;i<5;i++)

{ st2.push(i+10);

}

for(int i=1;i<5;i++)

{ System.out.println(st1.pop());

}

for(int i=1;i<5;i++)

{ System.out.println(st2.pop());

}

}

}

Output:
4
3
2
1
14
13
12
11

Example: This example demonstrates that an interface can be extended. This example also illustrates that a class implementing the extended interface must implement methods in base interface as well as methods in the extended interface.

interface ExtStackInterface extends StackInterface

{ public boolean isStackEmpty();

public boolean isStackFull();

public void display();

}

class ExtStack implements ExtStackInterface

{ int top = -1; int a[] = new int[10];

public void push(int x)

{ if(top == 9)

{ System.out.println("Stack Full"); return;

}

top = top + 1; a[top] = x;

}

public int pop()

{ if(top ==  -1)

{ System.out.println("Stack Empty");

return -1; //assuming that -1 is not a valid data

}

}

public void display()

{ for(int i = top; i >= 0; i--)

int x = a[top]; top = top - 1; return x;

{ System.out.println(a[i]);

}

}

public boolean isStackEmpty()

{ if(top == -1)

return(true);

else

return(false);

}

public boolean isStackFull()

{ if(top == 9)

return(true);

else

return(false);

}

}

Example: This example demonstrates that a class implementing the interface can also extend a base class. The implementing class must provide the implementation of all the methods in the interface. But the methods defined in the super-class need not be implemented as their definition is inherited from the super-class.

class ExtStack extends Stack implements ExtStackInterface

{ public void display()

{ for(int i = top; i >= 0; i--)

{ System.out.println(a[i]);

}

}

public boolean isStackEmpty()

{ if(top == -1)

return(true);

else

return(false);

}

public boolean isStackFull()

{ if(top == 9)

return(true);

else

return(false);

}

}

Thursday, 4 June 2015

Java Interface Characteristics

  1. Interface can be declared as abstract but it is superfluous and seldom done.
  2. Since interfaces are meant to be implemented by classes, interface members implicitly have public accessibility and the public modifier is omitted.
  3. The methods in an interface are all implicitly abstract and public. A method prototype has the same syntax as an abstract method. However, only the modifiers abstract and public are allowed, but these are normally omitted.
  4. A class can neither narrow the accessibility of an interface method nor specify new exceptions in method’s throws clause; as attempting to do so would amount to altering the interfaces contract, which is illegal. The criteria for overriding methods also apply when implementing interface methods.
  5. Interface methods cannot be declared as static. They are always implemented as instance methods.
  6. Regardless of how many interfaces a class implements directly or indirectly, it only provides a single implementation of a method that might have multiple declarations in the interfaces.
  7. Method prototype declarations can also be overloaded as in the case of classes.
  8. An interface can also define named constants. Such constants are defined by field declarations and are considered to be public, static and final. These modifiers are usually omitted from the declaration. Such a constant must be initialized with an initializer expression.
  9. An interface constant can be accessed by any client (a class or interface) using its fully qualified name, regardless of whether the client extends or implements its interface.
    However, if a client is a class that implements this interface or an interface that extends this interface, then the client can also access such constants directly without using the fully qualified name. Such a client inherits the interface constants.
  10. In the case of multiple inheritance of interface constants, any name conflicts can be resolved using fully qualified names for the constants involved.

Java accessing Interface Variables

The variables defined in an interface are implicitly public, static and final as discussed earlier.

The variables can be accessed just like static variables by using name of the interface and dot operator. The following example demonstrates this.

Example:

interface Constants

{

double PI = 3.1415;

double E = 2.712;

float INT_RATE = 10.0f;

}

These constants can be referred from other classes as follows:

Constants.PI, Constants.E, Constants.INT_RATE

The constants defined in the interface Constants can be accessed simply by using their names as PI, E and INT_RATE in the class, which implements the interface Constants.

You can use interfaces to import shared constants into multiple classes by simply declaring an interface that contains variables, which are initialized to the desired values.

When you include that interface in a class (i.e., when you “implement the interface”), all of these variables name will be in scope as constants. This is similar to using header file in C/C++ to create a large number of #defined constants or const declarations.

If an interface contains no methods, then any class that includes such an interface does not actually implement anything. It is as if that class was importing the constant variables into the class name space as final variables.

Example:

interface SharedConstants

{

int NO = 0;

int YES = 1;

int MAYBE = 2;

int LATER = 3;

int SOON = 4;

int NEVER = 5;

}

class ConstantsDemo implements SharedConstants

{

public static void main(String args[])

{

System.out.println(NO);

System.out.println(YES);

System.out.println(MAYBE);

System.out.println(LATER);

System.out.println(SOON);

System.out.println(NEVER);

}

}

class ConstantsDemo1

{

public static void main(String args[])

{

System.out.println(SharedConstants.NO);

System.out.println(SharedConstants.YES);

System.out.println(SharedConstants.MAYBE);

System.out.println(SharedConstants.LATER);

System.out.println(SharedConstants.SOON);

System.out.println(SharedConstants.NEVER);

}

}

Output: Output of executing both classes will be same as shown below:

0
1
2
3
4
5

Note: Class “ConstantsDemo” can use the constants defines in the interface  “SharedConstants” without qualifying with the interface name as it implements the interface “SharedConstants”. But class “ConstantsDemo1” can use the constants defined in the interface “SharedConstants” only after qualifying with the interface name, as it does not implement the interface “SharedConstants”.

Java extending an Interface

One interface can inherit another by use of keyword extends. The syntax is the same as for inheriting classes. When a class implements an interface that inherits another interfaces, it must provide implementations for all methods defined within the interface inheritance chain.

Example:

interface A

  void m1();
  void m2();
}

interface B extends A //interface can be extended
{
  void m3();
}

class MyClass implements B
{
   public void m1()
  {
    System.out.println("m1");
  }

public void m2()
{
   System.out.println("m2");
}

public void m3()
{
   System.out.println("m3");
}

}

class InterfaceExtendDemo
{

public static void main(String args[])

{

MyClass ob=new MyClass();

ob.m1();

ob.m2();

ob.m3();

}

}

Output:
m1
m2
m3

Java implementing an Interface

Once an interface has been defined, one or more classes can implement that interface. To implement an interface, include the implements clause in a class definition, and then create the methods defined by the interface.

The simplest form of a class implementing an interface is:

modifiers class <class-name> implements <interface-name>

{

body of the class

}

The body of the class must provide implementations of the methods declared in the interface.

You can also add additional features in the implementing class.

The methods that implement an interface must be declared public. Also, the signature of the implementing methods must match exactly the signature specified in the interface definition.

Java does not support multiple-inheritance but it supports multiple interface inheritance i.e. a class can implement any number of interfaces as shown below:

modifiers class <class-name> implements <interface-1>, <interface-2>, ……..<interface-n>

{

body of the class

}

The implementing class must provide body of all the methods in all the interfaces otherwise it must be declared as abstract.

The implementing class may also extend a class and can implement multiple interfaces. The most general form of a class that includes the implements clause looks like this:

modifiers class className [extends super-class] [implements interface1, interface2...]

{

class-body

}

Example:

interface Callback

{

void callback(int x);

}

Following is an implementation of the Callback interface

class Client1 implements Callback

{ public void callback(int x)

{ System.out.println(“Client1: ”+x);

}

}

Notice that callback method is declared using public access specifier. When you implement an interface method, it must be declared as public. The implementing an interface method is like over-riding so we cannot decrease the visibility.

1. Non Interface Methods

It is both permissible and common for classes that implement interfaces to define additional members of their own. For example, the following version of client implements callback() and adds the method m1():

class Client2 implements Callback

{ public void callback(int x)

{ System.out.println("Cleint2: " + 2*x);

}

public void m1()

{ System.out.println("m1 of Client2");

}

}

2. Accessing Implementations through Interface References

You can declare variables as object references that use an interface rather than a class type. Any instance of any class that implements the declared interface can be referred to by such a variable.

When you call a method through one of these references, the correct version will be called based on the actual instance of the interface being referred to. This is one of the key features of interfaces.

The method to be executed is looked up dynamically at run time, allowing classes to be created later than the code, which calls methods on them. The calling code can dispatch through an interface without having to know anything about the “callee”. This process is similar to using a super class reference to access a sub class object.

Note: Because dynamic lookup of a method at run time incurs a significant overhead when compared with the normal method invocation in Java, you should be careful not to use interface casually in performance-critical code.

Example: The following example demonstrates invoking method via an interface reference variable:

interface Callback

{ void callback(int x);

}

class Client1 implements Callback

{ public void callback(int x)

{ System.out.println("Client1: "+x);

}

}

class Client2 implements Callback

{ public void callback(int x)

{ System.out.println("Cleint2: " + 2*x);

}

public void m1()

{ System.out.println("m1 of Client2");

}

}

class InterfaceDemo1 //Accessing implementation through interface

{ public static void main(String args[])

{ Callback c = new Client1();

c.callback(10);

Callback c1 = new Client2();

c1.callback(10);

//c1.m1();

Client2 c2 = (Client2)c1;

c2.m1();

}

}

Output:

Client1: 10

Cleint2: 20

m1 of Client2

Notice that variable c is declared to be of interface type Callback, yet it is assigned an instance of Client1.

Although c1 can be used to access the callback() method, it cannot access any other members of the class Client2. An interface reference variable only has knowledge of the methods declared by its interface declaration.

Thus, c1 could not be used to access m1() method since it is defined by Client2 but not by Callback interface.

3. Polymorphic Power of Interface Reference Variable

The following example demonstrates the Polymorphic power of interface reference variable:

class InterfaceDemo2 //Polymorphic power of interface reference

{ public static void main(String args[])

{ Callback c;

Client1 c1  = new Client1();

Client2 c2  = new Client2();

c = c1;

c.callback(10);

c = c2;

c.callback(10);

}

}

Output:

Client1: 10
Cleint2: 20

4. Partial Implementation

If a class implements an interface but does not fully implement the methods defined by that interface, then that class must be declared as abstract.

Example:

abstract class Incomplete implements Callback

{ private int x;

void show()

{ System.out.println(x);

}

}

Here, the class Incomplete does not implement callback() method and must be declared as abstract. Any class that inherits Incomplete must implement callback() or be declared abstract itself.

Java defining an Interface

The general form of an interface is like class as shown below.

modifiers interface <interfac_name>

{ modifiers return_type method1(parameter-list);

modifiers return_type method2(parameter-list);

.

modifiers type final_var1 = value1;

modifiers type final_var2 = value2;

.

}

1. Modifiers for Top-Level Interface

The only modifiers that can be used with the top-level interfaces are abstract and public.

Even if we do not use abstract modifier, the interface is implicitly declared to be abstract so use of modifier abstract is redundant.

The visibility of a top-level interface can be either package or public just like top-level class. If no visibility modifier is used then the visibility of the interface is assumed to be package.

2. Interface Methods

Methods declared in an interface have no body. They end with a semicolon after the parameter list. They are, essentially, abstract methods and there can be no default implementation of any method specified within an interface.

All the methods declared in an interface have two modifiers, which are implicit:

abstract public method(parameter-list);

Methods are always abstract, which means they do not have any body and have public access.

All the methods declared in an interface are instance methods to be defined in the sub-classes.

We cannot declare static methods in interfaces.

3. Interface Data Members

We can define only constants in the interfaces.  All the variables in an interface are implicitly public, final and static meaning they cannot be changed by the implementing class. They must also be initialized with constant value.

Variables in an interface have implicit modifiers as shown below:

public static final int x = 10;

The variable x is public, static and final. It means it is a static variable with public access. The variable is also declared final, which means that it must be assigned a value at the time of declaration, which cannot be modified later on. The keyword final is like const in C/C++.

Example: The following program defines an interface for a stack i.e. it abstracts the public part of the stack.

interface StackInterface

{ void push(int x);

int pop();

}

The interface specifies that the stack has just two operations and any class sub-classing (implementing) this interface must provide bodies of push() and pop() methods.

Java Interface introduction

The purpose of the interface is to separate a class’s interface from its implementation. Interface just defines what a class must do without saying anything about the implementation. Interfaces define only method signatures and they do not have any instance variables. Interfaces are very good tool for designing as you can just define signatures of public methods without going into
implementation details, which are left for the person implementing the interface.

Using the keyword interface, you can fully abstract a class‘s interface from its implementation. That is, using interface, you can specify what a class must do, but not how it does it.

Interfaces are syntactically similar to classes, but they lack instance variables, and their methods are declared without any body. In practice, this means that you can define interfaces, which do not make assumptions about how they are implemented. Once it is defined, any number of classes can implement an interface. Also, one class can implement any number of interfaces.

To implement an interface, a class must create the complete set of methods defined by the interface. However, each class is free to determine the details of its own implementation. By providing the interface keyword, Java allows you to fully utilize the “one interface, multiple methods” aspect of polymorphism.

Interfaces are designed to support dynamic method resolution at run time. They disconnect the definition of a method or set of methods from the inheritance hierarchy. Since interfaces are in a different hierarchy from classes, it is possible for classes that are unrelated in terms of class hierarchy to implement the same interface. This is where the real power of interfaces is realized.

Note: Interfaces add most of the functionality that is required for many applications, which would normally resort to using multiple inheritance in a language such as C++.