Fundamentals (Docs)



There are a number of situations in software engineering when it is important for disparate groups of 
programmers to agree to a "contract" that spells out how their software interacts. Each group should be able
 to write their code without any knowledge of how the other group's code is written. Generally speaking, 
interfaces are such contracts.

Interfaces in Java

In the Java programming language, an interface is a reference type, similar to a class, that can contain only
 constants, method signatures, and nested types. There are no method bodies. 
Interfaces cannot be instantiated - they can only be implemented by classes or extended by other interfaces.

	public interface OperateCar {

	   // constant declarations
	   int ENGINE = 1;

	   // method signatures
	   int signalTurn(Direction direction, boolean signalOn);

Note that the method signatures have no braces and are terminated with a semicolon.

To use an interface, you write a class that implements the interface. 
When an instantiable class implements an interface, it provides a method body for each of the methods declared 
in the interface.

	public class OperateBMW implements OperateCar {

	   int signalTurn(Direction direction, boolean signalOn) {
	      //code to turn BMW's LEFT turn indicator lights on
	      //code to turn BMW's LEFT turn indicator lights off

	   // other members, as needed
	   // not visible to clients of the interface

Chevrolet's implementation will be substantially different from that of Toyota, of course, but both manufacturers will
 adhere to the same interface.

Multiple Inheritance

The Java programming language does not permit multiple inheritance (inheritance is discussed later in this 
lesson), but interfaces provide an alternative.
In Java, a class can inherit from only one class but it can implement more than one interface. 

Defining an Interface

An interface declaration consists of modifiers, the keyword interface, the interface name, 
a comma-separated list of parent interfaces (if any), and the interface body. 

	public interface GroupedInterface extends Interface1, Interface2, Interface3 {

	   // constant declarations
	   double E = 2.718282;

	   // method signatures
	   void doSomething (int i, double x);
	   int doSomethingElse(String s);

The public access specifier indicates that the interface can be used by any class in any package. 
If you do not specify that the interface is public, your interface will be accessible only to classes defined 
in the same package as the interface.

A class can extend only one other class, an interface can extend any number of interfaces.

All methods declared in an interface are implicitly public, so the public modifier can be omitted.

All constant values defined in an interface are implicitly public, static, and final. 
Once again, these modifiers can be omitted.

Implementing an Interface

To declare a class that implements an interface, you include an implements clause in the class declaration.

	public interface Relatable {
	   // this (object calling isLargerThan) and
	   // other must be instances of the same class
	   // returns 1, 0, -1 if this is greater
	   // than, equal to, or less than other
	   public int isLargerThan(Relatable other);

Any class can implement Relatable if there is some way to compare the relative "size" of objects instantiated 
from the class. For strings, it could be number of characters; for books, it could be number of 
pages; for students, it could be weight.

If you know that a class implements Relatable, then you know that you can compare the size of the objects
 instantiated from that class.

	package interfacesdemo;

	public class InterfacesDemo {

	    public static void main(String[] args) {
		RectanglePlus obj1 = new RectanglePlus(30, 30);
		RectanglePlus obj2 = new RectanglePlus(30, 20);
		System.out.println("Obj2 is largen than Obj1: " + obj2.isLargenThan(obj1));

	interface Relatable {
	    public int isLargenThan(Relatable other);

	class RectanglePlus implements Relatable {
	    public int width = 0;
	    public int height = 0;
	    public RectanglePlus(int w, int h) {
		width = w;
		height = h;
	    public int getArea() {
		return width * height;
	    public int isLargenThan(Relatable other) {
		RectanglePlus otherObj = (RectanglePlus) other;
		return (this.getArea() > otherObj.getArea() ? 1 : -1);

Be aware of the line: RectanglePlus otherObj = (RectanglePlus) other;

Type casting tells the compiler what the object really is. 
Invoking getArea directly on the other instance (other.getArea()) would fail to compile 
because the compiler does not understand that other is actually an instance of RectanglePlus.

Rewriting Interfaces

Consider an interface that you have developed called DoIt:

	public interface DoIt {
	   void doSomething(int i, double x);
	   int doSomethingElse(String s);

Suppose that, at a later time, you want to add a third method to DoIt, so that the interface now becomes:

	public interface DoIt {
	   void doSomething(int i, double x);
	   int doSomethingElse(String s);
	   boolean didItWork(int i, double x, String s);

If you make this change, all classes that implement the old DoIt interface will break because they don't 
implement the interface anymore. Programmers relying on this interface will protest loudly.

To anticipate all uses for your interface and to specify it completely from the beginning is often impossible.
You may need to create more interfaces later.

	public interface DoItPlus extends DoIt {
	   boolean didItWork(int i, double x, String s); 

Now users of your code can choose to continue to use the old interface or to upgrade to the new interface.