Tuesday, 21 January 2014

Difference between Abstract class vs Interface in Java and When to use them

When to use interface and abstract class is one of the most popular object oriented design questions and almost always asked in Java, C# and C++ interviews. In this article, we will mostly talk in context of Java programming language, but it equally applies to other languages as well. Question usually starts with difference between abstract class and interface in Java, which is rather easy to answer, especially if you are familiar with syntax of Java interface and abstract class. Things start getting difficult when interviewer ask about when to use abstract class and interface in Java, which is mostly based upon solid understanding of popular OOPS concept like Polymorphism, Encapsulation, Abstraction, Inheritance and Composition. Many programmer fumbles here, which is natural because most of them haven't gone through real system design process and haven’t seen the impact of choosing one over other. Repercussion of design decisions are best known during maintenance phase, a good design allows seamless evolution while maintaining a fragile design is nightmare. As I have said previously, some time object oriented design interview questions also helps to understand a topic better, but only if you are willing to do some research and not just mugging the answer. Questions like when to use abstract class and interface falls under same category. In order to best understand this topic, you need to work out some scenarios, examples etc. It's best to get this kind of knowledge as part of your work but even if you don't get there, you can supplement them by reading some good books like Head First design pattern and doing some object-oriented software design exercises. In this article, we will learn difference between abstract class and interface in Java programming language and based upon our understanding of those differences, we will try to find out some tips and guidelines to decide when its better to use abstract class over interface or vice-versa.


Difference between abstract class and interface in Java

Abstract Class vs Interface in Java and When to use them over otherWhile deciding when to use interface and abstract class, it’s important to know difference between abstract class and interface in Java. In my opinion, following two differences between them drives decision about when to use abstract class or interface in Java.

1) Interface in Java can only contains declaration. You can not declare any concrete methods inside interface. On the other hand abstract class may contain both abstract and concrete methods, which makes abstract class an ideal place to provide common or default functionality. I suggest reading my post 10 things to know about interface in Java to know more about interfaces, particularly in Java programming language.

2) Java interface can extend multiple interface also Java class can implement multiple interfaces, Which means interface can provide more polymorphism support than abstract class . By extending abstract class, a class can only participate in one Type hierarchy but by using interface it can be part of multiple type hierarchies. E.g. a class can be Runnable and Displayable at same time. One example I can remember of this is writing GUI application in J2ME, where  class extends Canvas and implements CommandListener to provide both graphic and event-handling functionality..

3) In order to implement interface in Java, until your class is abstract, you need to provide implementation of all methods, which is very painful. On the other hand abstract class may help you in this case by providing default implementation. Because of this reason, I prefer to have minimum methods in interface, starting from just one, I don't like idea of marker interface, once annotation is introduced in Java 5. If you look JDK or any framework like Spring, which I does to understand OOPS and design patter better, you will find that most of interface contains only one or two methods e.g. Runnable, Callable, ActionListener etc.

I haven't included all syntactical difference between abstract class and interface in Java here, because focus here to learn when to use abstract class and interface and choosing one over other. Nevertheless you can see difference between interface and abstract class to find  all those syntactical differences.

When to use interface and abstract class in Java

As I said earlier, it's easy to answer questions like difference between abstract class and interface in Java, but difficult to answer follow-ups. Though most of  Java Interview starts with former one, later it goes to see if you have really used abstract class and interface or not. In order to answer this question, you need to have good understanding of OOPS concepts like Polymorphism, Encapsulation, Abstraction and Inheritance. Also familiarity with coupling and cohesion is important. You at least should know that effort of designing should lead to reduce coupling and increased cohesion, ease of maintenance etc. In this part, we will see some scenarios, guidelines, rules which can help you to decide when to use abstract class and interface in Java.

1) In Java particularly, decision between choosing Abstract class and interface may influence by the fact that multiple inheritance is not supported in Java. One class can only extend another class in Java. If you choose abstract class over interface than you lost your chance to extend another class, while at the same time you can implement multiple interfaces to show that you have multiple capability. One of the common example, in favor of interface over abstract class is Thread vs Runnable case. If you want to execute a task and need run() method it's better to implement Runnable interface than extending Thread class.

2) Let's see another case where an abstract class suits better than interface. Since abstract class can include concrete methods, it’s great for maintenance point of view, particularly when your base class is evolving and keep changing. If you need a functionality across all your implementation e.g. a common method, than, you need to change every single implementation to include that change if  you have chosen interface to describe your base class. Abstract class comes handy in this case because you can just define new functionality in abstract super class and every sub class will automatically gets it. In short, abstract class are great in terms of evolving functionality. If you are using interface, you need to exercise extra care while defining contracts because its not easy to change them once published.

3) Interface in Java is great for defining Types. Programming for interfaces than implementation is also one of the useful Object oriented design principle which suggests benefit of using interface as argument to function, return type etc.

4) One more general rule of when to use abstract class and interface is to find out whether a certain class will form a IS-A hierarchy or CAN-DO-THIS hierarchy. If you know that you will be creating classes e.g. Circle, Square than it's better to create an abstract class Shape which can have area() and perimeter() as abstract method, rather than defining Shape as interface in Java. On the other hand if you are going to create classes which can do thinks like, can fly, you can use interface Flyable instead of abstract class.

5) Interface generally define capability e.g. Runnable can run(), Callable can call(), Displayable can display(). So if you need to define capability, consider using interface. Since a class can have multiple capabilities i.e. a class can be Runnable as well as Displayable at same time. As discussed in first point, Since java does not allow multiple inheritance at class level, only way to provide multiple capability is via interfaces.


6) Let's see another example of where to use Abstract class and Interface in Java, which is related to earlier point. Suppose you have lot of classes to model which are birds, which can fly, than creating a base abstract class as Bird would be appropriate  but if you have to model other things along with Birds, which can fly e.g. Airplanes, Balloons or Kites than it's better to create interface Flyable to represent flying functionality. In conclusion, if you need to provide a functionality which is used by same type of class than use Abstract class and if functionality can be used by completely unrelated classes than use interface.

7) Another interesting use of Abstract class and interface is defining contract using interface and providing skeletal using abstract class. java.util.List from Java collection framework is a good example of this pattern. List is declared as interface and extends Collection and Iterable interface and AbstractList is an abstract class which implements List. AbstractList provides skeletal implementation of List interface. Benefit of using this approach is that it minimize the effort to implement this interface by concrete class e.g. ArrayList or LinkedList. If you don't use skeletal implementation e.g. abstract class and instead decide to implement List interface than not only you need to implement all List methods but also you might be duplicating common code. Abstract class in this case reduce effort to implement interface.

8) Interface also provide more decoupling than abstract class because interface doesn't contain any implementation detail, while abstract class may contain default implementation which may couple them with other class or resource.

9) Using interface also help while implementing Dependency Injection design pattern and makes testing easy. Many mock testing framework utilize this behavior.

That's all on When to use Abstract class and interface in Java. Though discussion here is centered around Java but given concept of abstract class and interface goes beyond Java and also applicable to other Object oriented language, some of the tips are also applicable to other OOPS languages. Key thing to remember here is there definition of abstract class and interface e.g. in C++ and C# it varies a lot like in C++ and Java. Single most difference is multiple inheritance. We have also discussed some key differences between abstract class and interface in Java, which influence decision of choosing abstract class over interface or vice-versa. Last thing to remember is that interface is extremely difficult to evolve, so put extra care while designing interfaces.

PS: Effective Java, which is one of the best book on Java programming also has couple of items on interface and abstract class. Joshua Bloch has advised to prefer interface over abstract class in some scenario, which is worth reading.

$$ $$How to Find if Linked List contains Loops or Cycles in Java - Coding Question$$,$$
Write a Java program to check if a linked list is circular or cyclic,  and how do you find if a linked list contains loop or cycles in Java are some common linked list related data structure interview questions asked in various Java Interviews. This is some time asked as follow-up question of basic linked list questions like inserting element at beginning, middle and end of linked list or finding length of linked list. In order to solve linked list related algorithmic question in Java, you need to be familiar with concept of singly linked list, doubly linked list and circular linked list. Until stated specifically, most questions are based on singly linked list. For those who are not familiar of linked list data structure, its a collection of nodes. Each node contains two parts data and address, where address part points to another node in linked list. Last node of linked list, often referred as tail points to null. Also a singly list can only move in one direction, towards end. Now, let's come back to this question. Good thing about this question is that, it can also be solved by using two pointer approach discussed in How to find middle element of linked list in single pass. If a linked list contains a loop or cycle it is known as circular or cyclic linked list. As I said we can use two pointer approach to check if a linked list is circular or not.


Algorithm to find if linked list contains loops or cycles

Two pointers, fast and slow is used while iterating over linked list. Fast pointer moves two nodes in each iteration, while slow pointer moves to one node. If linked list contains loop or cycle than both fast and slow pointer will meet at some point during iteration. If they don't meet and fast or slow will point to null, then linked list is not cyclic and it doesn't contain any loop. Here is exact algorithm

1) Use two pointers fast and slow
2) Move fast two nodes and slow one node in each iteration
3) If fast and slow meet then linked list contains cycle
4) if fast points to null or fast.next points to null then linked list is not cyclic

Next section contains Java program to check if linked list contains loop or cycle, which is exact implementation of above algorithm. This algorithm is also known as Floyd’s cycle finding algorithm and popularly known as tortoise and hare algorithm to find cycles in linked list.

Java program to check if linked list is circular or not.

This Java program uses LinkedList(not java.util.LinkedList)  and Node class from previous example of Linked List, with modification of adding toString() method and appendToTail() method. Also, isCyclic() method of linked list is used to implement logic to find if linked list contains cycle or not. Subsequently isCyclic() returns true if linked list is cyclic otherwise it return false.

/*
 * Java class to represent linked list data structure.
 */
public class LinkedList {
    private Node head;
    public LinkedList() { this.head = new Node("head"); }   
    public Node head() { return head;}
   
    public void appendIntoTail(Node node) {
        Node current = head;
       
        //find last element of LinkedList i.e. tail
        while(current.next() != null){
            current = current.next();
        }
        //appending new node to tail in LinkedList
        current.setNext(node);
    }
   
    /*
     * If singly LinkedList contains Cycle then following would be true
     * 1) slow and fast will point to same node i.e. they meet
     * On the other hand if fast will point to null or next node of
     * fast will point to null then LinkedList does not contains cycle.
     */
    public boolean isCyclic(){
        Node fast = head;
        Node slow = head;
       
        while(fast!= null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
           
            //if fast and slow pointers are meeting then LinkedList is cyclic
            if(fast == slow ){
                return true;
            }
        }
        return false;
    }
   
    @Override
    public String toString(){
        StringBuilder sb = new StringBuilder();
        Node current = head.next();
        while(current != null){
           sb.append(current).append("-->");
           current = current.next();
        }
        sb.delete(sb.length() - 3, sb.length()); // to remove --> from last node
       return sb.toString();
    }

    public static class Node {
        private Node next;
        private String data;

        public Node(String data) {
            this.data = data;
        }

        public String data() { return data; }
        public void setData(String data) { this.data = data;}

        public Node next() { return next; }
        public void setNext(Node next) { this.next = next; }

        @Override
        public String toString() {
            return this.data;
        }
    }
}

Testing linked list for cycle or loop

In this section we will test linked list using Java main method with two linked list, one contains cycle and other is not cyclic. You can even write JUnit test cases for isCyclic() method to test different linked list with circles and loops at different positions. Here is first test where linked list does not contain any cycle.
/**
 *
 * Java program to find if LinkedList contains loop or cycle or not.
 * This example uses two pointer approach to detect cycle in linked list.
 * Fast pointer moves two node at a time while slow pointer moves one node.
 * If linked list contains any cycle or loop then both pointer will meet some time.
 *
 * @author Javin Paul
 */
public class LinkedListTest {

    public static void main(String args[]) {

        //creating LinkedList with 5 elements including head
        LinkedList linkedList = new LinkedList();
        linkedList.appendIntoTail(new LinkedList.Node("101"));
        linkedList.appendIntoTail(new LinkedList.Node("201"));
        linkedList.appendIntoTail(new LinkedList.Node("301"));
        linkedList.appendIntoTail(new LinkedList.Node("401"));

        System.out.println("Linked List : " + linkedList);

        if(linkedList.isCyclic()){
            System.out.println("Linked List is cyclic as it contains cycles or loop");
        }else{
            System.out.println("LinkedList is not cyclic, no loop or cycle found");
        }    

    } 
   
}

Output:
Linked List : 101-->201-->301-->401
LinkedList is not cyclic, no loop or cycle found

Now let's change the linked list so that it contains cycle or loop,
//creating LinkedList with 5 elements including head
LinkedList linkedList = new LinkedList();
linkedList.appendIntoTail(new LinkedList.Node("101"));
LinkedList.Node cycle = new LinkedList.Node("201");
linkedList.appendIntoTail(cycle);
linkedList.appendIntoTail(new LinkedList.Node("301"));
linkedList.appendIntoTail(new LinkedList.Node("401"));
linkedList.appendIntoTail(cycle);

//don't call toString method in case of cyclic linked list, it will throw OutOfMemoryError
//System.out.println("Linked List : " + linkedList);

if(linkedList.isCyclic()){
   System.out.println("Linked List is cyclic as it contains cycles or loop");
}else{
   System.out.println("LinkedList is not cyclic, no loop or cycle found");
}    

Output:
Linked List is cyclic as it contains cycles or loop

Let me show you an interesting point here, in case you have not noticed already. This is also asked in interviews as, do you see anything suspicious? toString() method of LinkedList class is not checking for cycles or loop and it will throw Exception in thread "main" java.lang.OutOfMemoryError: Java heap space, if you try to print a linked list with cycles. Now, if you are really lucky then they may ask you to find start of loop in linked list. That's exercise for you, but let me give you a hint, look at below diagram of a linked list which contains cycle, red element is the start of cycle. What is special about it? If you look closely, you can see that it's the only node in whole linked list which is next node of other two pointers.
Loop or Cycle detection in Java linked list




No comments:

Post a Comment