Monday, May 18, 2015

Power multiplier: combining the flexibility of interface and code-reusability of abstract class

Let's say we have an interface: ParentFace, which specifies 2 methods for parents to punish the child: either to spank them or to ground them. Any Parent class can implement this interface and implement these 2 methods.

However, considering this situation: all parents spank the child the same way and the implementation of this method doesn't need to be changed through out the program.

You might be thinking of instead of creating an interface, we can create an abstract class and write the spankChild() method as an concrete implementation while leaving the groundChild() as an abstract method for subclasses to implement.

While this approach does the trick here but it loses the flexibility of using an interface since one class can only inherit from one parent class while interfaces does not have this limitation.

1
2
3
4
public interface ParentFace {
 void spankChild();
 void groundChild();
}


The trick here is to create an abstract class that implements this interface as the following code snippet:



1
2
3
4
5
6
7
8
9
public abstract class StrictParent  implements ParentFace  {
 @Override
 public void spankChild() {
  System.out.println("Kick in the ass!"); 
 }

 @Override
 public abstract void groundChild();
}

The benefit of doing so is that we can re-use the code within the abstract class StrickParent while taking advantages of the flexibility of the interface ParentFace by passing the subclasses as the interface type.

Here comes my parent - MyParent, who always spank the child before grounding him :-(
We can refer MyParent Instance either as StrictParent type or ParentFace type since its parent class has implemented the ParentFace interface.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public class MyParent extends StrictParent{

 @Override
 public void groundChild() {
  // Let's punish the child first before grounding him or her
  spankChild();
  
  System.out.println("Ground the child for 2 days!");
  
 }
}

Now it's time to test out our code. In the Main method, we define a showMessage method which takes a ParentFace type instance as the parameter.

This is all the magic of this technique: programming to the interface instead of the abstract class.

It shows that we can both pass in a subclass of StrictParent or an implementation of ParentFace.

Pretty Flexible, ha!


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class Main {
 
 
 public static void showMessage(ParentFace parent){
  parent.spankChild();
  parent.groundChild();
 }

 public static void main(String[] args) {
  
  // declare the type as the interface so that you can mock the Object later
  ParentFace mum = new MyParent();
  showMessage(mum);
  
  // this time try to mock the MyParent 
  mum = new ParentFace() {
   
   @Override
   public void spankChild() {
    System.out.println("pat on the back.");
   }

   @Override
   public void groundChild() {
    
    System.out.println("suspend his allowance.");
   }
  };
  
  showMessage(mum);
  
 }

}

The output of this program is:


Kick in the ass!
Kick in the ass!
Ground the child for 2 days!
pat on the back.
suspend his allowance.







No comments:

Post a Comment