in oop object oriented programming design pattern programming solid ~ read.

Why is Interface so important?

In this post we are going to talk about what Interface is and why it is so important.

What is Interface?

Interface is a contract that defines sets of methods that have to be implemented by whatever classes implementing the interface.

Why is Interface important?

Let's have a look at the following example.

Let's say we have two classes like the following.

package com.oop;

class Employee {  
  public void pay() {}
}

class Contractor {  
  public void pay() {}
}

In the above situation, you might be thinking about creating a superclass to hold pay() method cause you don't want to violate Dry Principle. Let's create one now.

package com.oop;

class Worker {  
  public void pay() {}
}

class Employee extends Worker {

}

class Contractor extends Worker {

}

Let's see how can we use pay() method.

package com.oop;

class Worker {  
  public void pay() {}
}

class Employee extends Worker {

}

class Contractor extends Worker {

}

class Demo {  
  public void runDemo() {
    Worker[] workers = new Worker[]{
      new Employee(),
      new Contractor(),
    }
    doDemo(workers);
  }

  private void doDemo(Worker[] workers){
    for ( Worker w : workder ) 
      w.pay();
  }
}

Since both Employee & Contractor extend from Worker class which has a method called pay(), we can guarantee that we can call pay().

Ok Let's add more classes there to see what is going to happen.

package com.oop;

class Worker {  
  public void pay() {}
}

class Employee extends Worker {

}

class Contractor extends Worker {

}

class Volunteer extends Worker {  
  public void pay() {
    throw new UnsupportedOperationException();
  }
}

class Demo {  
  public void runDemo() {
    Worker[] workers = new Worker[]{
      new Employee(),
      new Contractor(),
    }
    doDemo(workers);
  }

  private void doDemo(Worker[] workers){
    for ( Worker w : workder ) 
      w.pay();
  }
}

As you can see here we have a Volunteer class which doesn't need to be paid so we thrown an exception which is a violation of Interface Segregation Principle - You should split out your interfaces in such a way that you never implement something you can't implement.

Let's see how can we solve this problem with interfaces.

package com.oop;

interface Payable {  
  public void pay();
}

class Employee implements Payable {

}

class Contractor implements Payable {

}

class Volunteer implements Payable {  
  public void pay() {
    throw new UnsupportedOperationException();
  }
}

class Demo {  
  public void runDemo() {
    Payable[] workers = new Payable[]{
      new Employee(),
      new Contractor(),
    }
    doDemo(workers);
  }

  private void doDemo(Payable[] workers){
    for ( Payable w : workder ) 
      w.pay();
  }
}

Since Interface doesn't provide implementations of the pay() method, we lose the default behaviour of pay() method. Let's see how can we solve this problem.

package com.oop;

interface Payable {  
  void pay();
  public static class Implementation implements Payable {
  public void pay() { /* default behaviour */ }
  }
}

class Employee implements Payable {

}

class Contractor implements Payable {  
  private Payable delegate = new Payable.Implementation();
  public void pay(){ delegate.pay(); }
}

class Volunteer {

}

class Demo {  
  public void runDemo() {
    Payable[] workers = new Payable[]{
      new Employee(),
      new Contractor(),
    }
    doDemo(workers);
  }

  private void doDemo(Payable[] workers){
    for ( Payable w : workder ) 
      w.pay();
  }
}

Since in Java, you can put methods into interfaces and that's exactly what we are doing here.

End

Hope you guys have learnt something from this post and if you guys have any ideas or opinions please leave it below, thanks.

comments powered by Disqus