Thursday, 4 June 2015

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++.

Sunday, 31 May 2015

Java Importing packages

We discuss this concept with reference to previous example. Given that packages exist and are a good mechanism for compartmentalizing diverse classes from each other, it is easy to see why all of the built in Java classes are stored in packages.

There are no core java classes in the unnamed default package; all of the standard classes are stored in some named package.

Since classes within packages must be fully qualified with their package name or names, it could become tedious to type the long dot-separated package path name for every class you want to use. For this reason, Java includes the import statement to bring certain classes, or entire package into visibility. Once imported, a class can be referred to directly, using only its name.

Note: The import statement is a convenience to the programmer and is not technically needed to write a complete Java program. If you are going to refer to a few dozen classes in your application, however, the import statement will save a lot of typing.

In Java source file, import statements occur immediately following the package statement. (if it exists) and before any class/interface definitions.

The geneal form of import statement:

import pkg1 [.pkg2] [.pkg3].[classname | *];

Note: 

1. The star form may increase compilation time. However, the star form has absolutely no effect on the run-time performance or size of your classes.

2. All of the standard Java classes included with Java are stored in a package called java. The basic language functionality is stored in a package inside of the java package called java.lang. Normally, you have to import every package or class that you want to use, but since Java is useless without much of the functionalities in java.lang, it is implicitly imported by the compiler for all programs. This is equivalent to the following line being at the top of all of your programs:

import java.lang.*;

3. If a class with the same name exists in two different packages that you import using the star form, the compiler will remain silent, unless you try to use one of the classes. In that case, you will get a compile-time error and have to explicitly name the class specifying its package.

4. Any place you use a class name, you can use its fully qualified name, which includes its full package hierarchy. When a package is imported, only those items within the package declared as public will be available to non-subclasses in the importing code.

Java visibility of class members

Classes and packages are both means of encapsulating and containing the name space and scope of variables and methods. Packages act as containers for classes and other subordinate packages. Class act as container for data and method code. The class is Java’s smallest unit of abstraction. Because of the interplay between classes and packages, Java addresses five categories of visibility for class members:

1. Visibility within the class

2. Visibility in sub-classes in the same package

3. Visibility in non-sub classes in the same package

4. Visibility in sub-classes in different package

5. Visibility in classes that are neither in the same package nor are sub classes.

A top-level class or interface has only two possible access levels: default and public. When a class is declared public, it is accessible by any other code. If a class has default access, then it can only be accessed by other code within the same package.

The visibility of class members is summarized in the following table:


Note: The member visibility has meaning only if the class is visible. If visibility modifier of the class is default then even public members of the class will be visible only within the package.

Example:

Protection.java

package p1;

public class Protection

{

int n = 1;

private int n_pri = 2;

protected int n_pro = 3;

public int n_pub = 4;

public Protection()

{

System.out.println("Base Constructor");

System.out.println(n);

System.out.println(n_pri);

System.out.println(n_pro);

System.out.println(n_pub);

}

}

To compile: javac –d . Protection.java

Derived.java

package p1;

class Derived extends Protection

{

public Derived()

{

 System.out.println(n);

System.out.println("Derived Constructor");

//System.out.println(n_pri);

System.out.println(n_pro);

System.out.println(n_pub);

  }

}

To compile: javac –d . Derived.java

SamePackage.java

package p1;

class SamePackage

{

public SamePackage()

  {

Protection p = new Protection();

System.out.println("Same Package constructor");

System.out.println(p.n);

//System.out.println(p.n_pri);

System.out.println(p.n_pro);

System.out.println(p.n_pub);

}

}

To compile: javac –d . SamePackage.java

Protection2.java

package p2;

class Protection2 extends p1.Protection

{

Protection2()

{

System.out.println("Protection2 Constructor");

//System.out.println(n);

//System.out.println(n_pri);

System.out.println(n_pro);

System.out.println(n_pub);

}

}

To compile: javac –d . Protection2.java

OtherPackage.java

package p2;

class OtherPackage

{

OtherPackage()

{

p1.Protection p = new p1.Protection();

System.out.println("OtherPackage Constructor");

//System.out.println(p.n);

//System.out.println(p.n_pri);

//System.out.println(p.n_pro);

System.out.println(p.n_pub);

}

}

To Compile: javac –d . OtherPackage.java

Test1.java

package p1;

class Demo

{

public static void main(String args[])

{

Protection ob1 = new Protection();

Derived ob2 = new  Derived();

SamePackage ob3 = new SamePackage();

}

}

To Compile: javac –d . Test1.java

Output:

Base Constructor1234
Base Constructor1234
Derived Constructor134
Base Constructor1234
Same Package Constructor134

Test2.java

package p2;

class Demo

{

public static void main(String args[])

{

Protection2 ob1 = new Protection2();

OtherPackage ob2 = new OtherPackage();

}

}

To Compile: javac –d . Test2.java

Output:

Base Constructor1234
Protection2 Constructor
34
Base Constructor1234
OtherPackage Constructor
4