Wednesday 9 March 2011

Java Design Techniques – Using Interfaces Part - 1

Interfaces give you more polymorphism and design freedom than singly inherited families of classes, let us prove this statement. 

Consider an example of singly inherited families of classes.

abstract class Animal {
    abstract void talk();
}
class Dog extends Animal {
    void talk() {
        System.out.println("Woof!");
    }
}
class Cat extends Animal {
    void talk() {
        System.out.println("Meow.");
    }
}
class Interrogator {
    static void makeItTalk(Animal subject) {
        subject.talk();
    }
}
 
Given these set of classes and inheritance, it becomes mandatory for you to pass only objects of the family Animal to the makeItTalk() function. 

Remember a very good design never mandates you on any obvious scenario that might occur in future. As in case of the above example it does and hence it’s not a very good design to follow. This is where interfaces come and save you.

Using Interfaces make your design more flexible. Interfaces give you more polymorphism and design freedom than singly inherited families of classes, because with interfaces you don't have to make everything fit into one family of classes. 

For example:

interface Talkative {

    void talk();
}

abstract class Animal implements Talkative {

    abstract public void talk();
}

class Dog extends Animal {

    public void talk() {
        System.out.println("Woof!");
    }
}

class Cat extends Animal {

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

class Interrogator {

    static void makeItTalk(Talkative subject) {
        subject.talk();
    }
}

Given this set of classes and interfaces, later you can add a new class to a completely different family of classes and still pass instances of the new class to makeItTalk(). For example, imagine you add a new CuckooClock class to an already existing Clock family:

class Clock {
}

class CuckooClock implements Talkative {

    public void talk() {
        System.out.println("Cuckoo, cuckoo!");
    }
}

Because CuckooClock implements the Talkative interface, you can pass a CuckooClock object to the makeItTalk() method:

class Example {

    public static void main(String[] args) {
        CuckooClock cc = new CuckooClock();
        Interrogator.makeItTalk(cc);
    }
}

With single inheritance only, you'd either have to some how fit CuckooClock into the Animal family, or not use polymorphism. With interfaces, any class in any family can implement Talkative and be passed to makeItTalk(). This is why interfaces give you more polymorphism and design freedom than you can get with singly inherited families of classes.

1 comment:

  1. Well said Vinod. I think, it should be design principle than technique.

    Again....someone said....Good example makes content easier to understand. You did the same here.

    Thanks. Great going...

    ReplyDelete