Java-Interface

  • 100% abstract data structure.
  • It can contain only constant variables, abstract methods, classes and other interfaces.
  • An interface cannot contain non-abstract functions and variables.
  • We cannot create objects of an interface.
  • On compilation, an interface generates a .class extension file.

TestInterface1.java

interface Shapes {
    int i = 10; // implicit conversion to public static final int i = 10;
    void drawCircle(); // public abstract void drawCircle();
}

class DrawShape1 implements Shapes { //directly implementing Shapes
    public void drawCircle() { //Interface methods are implicitly public abstract
        System.out.println(
            "drawCircle() - implemented in DrawShape1.");
    }
    public void function1() {
        System.out.println(
            "function1()- implemented in DrawShape1.");
    }
}

class SomeClass extends DrawShape1 {
    //indirectly implementing Shapes via DrawShape1
}

class DrawShape2 implements Shapes { //directly implementing Shapes
    public void drawCircle() {
        System.out.println(
            "drawCircle() - implemented in DrawShape2.");
    }
    public void function1() {
        System.out.println(
            "function1()- implemented in DrawShape2.");
    }
}

class TestInterface1 {
    public static void main(String args[]) {
        /*DrawShape1 ds1 = new DrawShape1();
        ds1.drawCircle();
        ds1.function1();

        DrawShape2 ds2 = new DrawShape2();
        ds2.drawCircle();
        ds2.function1(); */

        Shapes s = new Shapes(); /*Shapes is abstract and cannot be instantiated*/

        Shapes s = new DrawShape2();
        s.drawCircle();
        s.function1(); /*cannot find symbol function1() in interface Shapes since function1() is invisible to Shape (reference variable s)*/
    }
}

TestInterface3.java

interface Circle {
    void drawCircle();
}

interface Square {
    void drawCircle(int radius);
    void drawSquare();
}

class DrawShape implements Circle, Square {
    public void drawCircle(int r) {
        System.out.println("This is a circle with a radius of " + r);
    }
    public void drawCircle() {
        System.out.println("This is a circle.");
    }
    public void drawSquare() {
        System.out.println("This is a square.");
    }
}

class TestInterface3 {
    public static void main(String args[]) {
        DrawShape ds1 = new DrawShape();
        ds1.drawCircle();
        ds1.drawCircle(10);
        ds1.drawSquare();
    }
}

TestInterface4.java

interface Circle {
    void drawCircle();
}
interface Square {
    void drawSquare();
}
class Triangle {
    public void drawCircle() {
        System.out.println(
            "This is a circle - in Triangle.");
    }
    public void drawTriangle() {
        System.out.println(
            "This is a triangle - in Triangle.");
    }
}

class DrawShape extends Triangle implements Circle, Square {
    public void drawCircle() {
        System.out.println(
            "This is a circle - in DrawShape.");
    }
    public void drawSquare() {
        System.out.println(
            "This is a square - in DrawShape.");
    }
}

class TestInterface4 {
    public static void main(String args[]) {
        DrawShape ds = new DrawShape();
        ds.drawCircle();
        ds.drawSquare();
        ds.drawTriangle();
    }
}

TestInterface5.java

interface Circle {
    void drawCircle();
}

interface Square extends Circle {
    void drawSquare();
}

interface CircleSquareTriangle extends
Circle, Square {
    void drawTriangle();
}


class DrawShape implements CircleSquareTriangle {
    public void drawCircle() {
        System.out.println("This is a circle.");
    }
    public void drawSquare() {
        System.out.println("This is a square.");
    }
    public void drawTriangle() {
        System.out.println("This is a triangle.");
    }
}

class TestInterface5 {
    public static void main(String args[]) {
        DrawShape ds1 = new DrawShape();
        ds1.drawCircle();
        ds1.drawTriangle();
        ds1.drawSquare();
    }
}

TestInterface6.java

interface Circle {
    void drawCircle();
}
interface Square {
    void drawSquare();
}
interface Triangle {
    void drawTriangle();
}

interface CircleSquareTriangle extends Circle, Square, Triangle { // Extending multiple interfaces
}

class DrawShape implements CircleSquareTriangle {
    public void drawCircle() {
        System.out.println("This is a circle.");
    }
    public void drawSquare() {
        System.out.println("This is a square.");
    }
    public void drawTriangle() {
        System.out.println("This is a triangle.");
    }
}

class TestInterface6 {
    public static void main(String args[]) {
        DrawShape ds1 = new DrawShape();
        ds1.drawCircle();
        ds1.drawTriangle();
        ds1.drawSquare();
    }
}
  • The modifier final with a method prevents it from being overridden. A final method cannot be overridden.

  • The modifier final with a class prevents it from being inherited. A final class cannot be inherited.

  • Return type of functions is not considered in overloading.

  • If the return type is non-primitive then we can use sub-type while overloading the method.

    public Rectangle doSomething() {
    }
    
    public Container doSomething() { //overriding
    }
    
  • While overriding a function the access modifier can only be broadened, widened, or strengthened.

  • While overriding a function if the data type of an identifier is changed in the overridden function, it becomes overloading.

  • Modifier abstract cannot be used in combination with final, private or static.

    abstract + final -> abstraction is resolved by overriding the functions, but final prevents the function from being overridden.

    abstract + private -> abstraction is resolved by overriding the functions in the sub-class, but private members are not inherited.

    abstract + static -> static methods can be referred to by qualifying using class-name. Abstract methods are not definitive and hence make no sense.

  • implements - has a relationship.

  • extends - is a relationship.

  • An interface can extend one or more interfaces.

  • A class can extend only one class.

  • A class can implement one or more interfaces.

  • An interface cannot extend a class, since nothing can be non-abstract in an interface.

  • In Java, multiple inheritance can be attained only with the involvement of interface(s).

  • Where ever an interface is expected, we can pass the instance of a class that directly or indirectly implements the interface.