1

Below is the diagram, where, if we just consider the implementations of List,

enter image description here

  1. AbstractList maintains the core behavior of list. To introduce the new implementation class MyList(say) one can inherit AbstractList and override(if necessary) required methods. By extending AbstractList. Additionally, class MyList is obeying the contract to behave like a list.

    class MyList extends AbstractList{..}
    
  2. Users can use collection hierarchy, as,

    AbstractList l = new ArrayList<String>();
    l.add("one"); //execute ArrayList's add method
    
  3. A class can also maintain composition relation with any list implementation(at runtime), by having

    AbstractList l;
    

    as member, that gets populated at runtime, with any list implementation.

So,

I would like to understand the clear reason, Why additionally interface List<E> is introduced?

note1: Intention is to understand, how to use interface. This not a duplicate question, because both abstract class and interface are used.I did not use the word 'instead of' or 'rather'

note2: Let us not get into java-8 default methods, as above collection hierarchy was designed with whatever was provided till java-7

Malachi
  • 608
overexchange
  • 2,265
  • 4
    "interfaces are essential for single-inheritance languages like Java and C# because that's the only way in which you can aggregate different behaviors into a single class..." class Book extends Content implements List<Page> - one couldn't do this with AbstractList, because there would be no way for Book to extend both Content and AbstractList simultaneously – gnat Jul 05 '15 at 02:33
  • @gnat wording is 'instead of' in your referred query. Here both are used, abstract class and interface – overexchange Jul 05 '15 at 02:35
  • 1
    The motivation is explained in the AbstractList documentation. Quote: "This class provides a skeletal implementation of the List interface to minimize the effort required to implement this interface backed by a "random access" data store (such as an array)." – rwong Jul 05 '15 at 02:35
  • So, Are we saying that multiple inheritance is the only reason in this case, to introduce interface List<E>? – overexchange Jul 05 '15 at 04:53
  • 1
    @overexchange No, also conceptual cleanness: List is purely a specification of interface, AbstractList has behaviour that could conceivably be wrong in some situations. Interface-only inheritance should be preferred when you do not need to inherit behaviour but only need to provide the capability of polymorphism. – Jules Jul 05 '15 at 05:21
  • 1
    @Jules Only advantage that I understand: Any class MyList that defines all of the required methods and obeys the general contract is preferred to implement an interface List, because the class Myclass(some business class) do not need to reside in the above class hierarchy. This has nothing to do with multiple inheritance or polymorphism. – overexchange Jul 05 '15 at 09:49

3 Answers3

7

Your question seems to stem from the wrong assumption that every List is also a subclass of AbstractList. While AbstractList offers versatile base implementations for a lot of methods, there might be reasons not to use this option.

It’s hard to find an example when looking to the public API only, but there is one: CopyOnWriteArrayList.

You will find much more once you understand that not every implementation is public, e.g. by looking at Collections.unmodifiableList and Collections.synchronizedList, both returning implementations not inheriting from AbstractList for a good reason. They have base classes which are more suitable to their task, UnmodifiableList extends UnmodifiableCollection and SynchronizedList extends SynchronizedCollection.

There can be other, application-specific reasons not to subclass AbstractList, in the end, the decision to make the entire Collection-API interface-based is fundamental and there is no reason to make an exception for List. It’s not different to why you should use the Collection interface instead of AbstractCollection or the Set interface instead of AbstractSet

Regarding how to use it… If it is about parameters or heap variables which ought to offer the maximum flexibility, of course, you should always use the least specific type that is required for the operation, e.g. the List interface, if it is required that the provided Collection has List semantic. As said, there are List types which do not extend AbstractList.

If it is about local variables within an implementation code, you might declare a variable to match the type of the actual implementation, e.g. ArrayList<X> l=new ArrayList<>(); to reduce the number of different types which occur in this code. But that still implies that there is no reason to refer to AbstractList. The only place where a reference is to AbstractList is feasible is in the extends AbstractList clause…

Holger
  • 216
  • java.util.Collections is container of all inner static class data models and algo. Why would it sit under AbstractList? So, yes you are right, this static impl has to program on interfaces.
  • ##2) If implementations like CopyOnWriteArrayList are sitting in subpackg (java.util.concurrent), then yes, CopyOnWriteArrayList has to program on interface as I said in this comment. Perfect answer!!!!

    – overexchange Jul 07 '15 at 03:32
  • one supplementary. Do you think the way we use interface Comparable , Callable & ActionListeneris different from usage of interface List, Set Collection? How do you see the difference? – overexchange Jul 07 '15 at 03:52
  • Comparable, Callable & ActionListener have only a single abstract method, thus, there is little sense in providing an abstract base class. Since Java 8, such interfaces are called functional interfaces and can be implemented using a lambda expression. Now that interfaces can have default methods, you’ll have to think about whether an interface is basically a function, i.e. has one primary abstract method, as then, you might want to provide default methods for all others. However, note that AbstractList maintains mutable state, i.e. the modCount. – Holger Jul 07 '15 at 08:04
  • Further, AbstractList is a skeleton for certain kind of list implementation (i.e. compare to AbstractSequentialList), thus is not that open to arbitrary interface implementations. It’s useful for a lot of implementations but not for all. That’s the reason why UnmodifiableList and SynchronizedList are not subclasses of AbstractList (in contrast to EmptyList), not because they are nested types of Collections but because the AbstractList’s base implementation is not suitable for their purpose. – Holger Jul 07 '15 at 08:07