AbstractCollection implements both the Iterable and Collection interfaces. However, Collection is a subinterface of Iterable. Would it not suffice just to have AbstractCollection implement Collection?
The Javadocs for AbstractCollection could be interpreted that AbstractCollection directly implements Collection and Iterable.
All Implemented Interfaces:
Iterable, Collection
However, a quick look at the source code indicates that it only directly implements Collection.
public abstract class AbstractCollection<E> implements Collection<E> {
Therefore, the Javadocs must be interpreted as saying that the class implements the given interfaces directly or indirectly. As you've indicated, there would be no need for AbstractCollection to implement Iterable directly, because it already implements Collection. The source code shows that it doesn't implement Iterable directly. It does suffice for AbstractCollection to implement only Collection directly.
Yes. It would suffice. But, explicitly listing both allows one to tell (by simple inspection) that AbstractCollection implements both Iterable and Collection (also, because it's abstract it doesn't necessarily implement either interface - but any concrete sub-class will).
Related
Following the hierarchy of the Collections Framework in Java, I struggle to understand where these 2 methods of the Iterator Interface are being implemented.
boolean hasNext();
E next();
The other 2 methods
default void remove()
default void forEachRemaining(Consumer<? super E> action)
have default implementations in the Iterator Interface itself (although they are probably overridden somewhere else too).
image source: https://www.javatpoint.com/collections-in-java
I know that depending on the hierarchy, for example Interface -> Interface -> Class, the implementation can be either in the interface itself as a default method or in the concrete class. But lets take for example the ArrayList, where in the whole hierarchy are the hasNext() and next() methods being implemented.
Collection implements Iterable and Iterable has the method iterator() that returns the Iterator interface, so implementations dont have to implement the Iterator interface.
If you take ArrayList for example, it inherits AbstractList which implements iterator and that is used by different lists implementations.
When I was seeing the declaration of ArrayList
class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
which implements List interface even though ArrayList's superclass AbstractList implements the same List interface.
abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>
Similar declarations can be found on HashMap, LinkedHashMap declarations also.
In the declaration of LinkedHashMap, it implements Map interface only and not the other interfaces implemented by its superclass HashMap.
So there might be some benefits of having such declarations.
There are no functional benefits to declaring them again, it does not affect the behavior in any way.
I guess it's only added to make it clearer which interfaces are implemented.
This is done for documentation purposes only, to make it immediately clear to the user of the class which interfaces the class implements.
The redundant implements clause makes no difference to the compiler.
Yes. It could've been omitted. But thus it is immediately visible that it is a List. Otherwise an extra click through the code / documentation would be required. I think that's the reason - clarity.
And to add what Joeri Hendrickx commented - it is for the purpose of showing that ArrayList implements List. AbstractList in the whole picture is just for convenience and to reduce code duplication between List implementations.
Reference: Why does ArrayList have "implements List"?
Totally unnecessary. I wouldn't do it at all.
It's unclear why they did that by then. But by now apparently it's a mistake, since everybody is surprised by it when they first notice this odd redundancy.
Well, this way you must implement List<E> methods when you create a subclass to AbstractList, and you can also use an ArrayList as an AbstractList.
ArrayList<T> and AbstractList<T> implement List<T> for different purposes.
List<T> establishes what is required for a class to be a list.
ArrayList<T> implements List<T> as part of defining its own interface. This is essential to what ArrayList<T> is.
ArrayList<T> extends AbstractList<T> as part of its own implementation. This is entirely optional: one could have implemented ArrayList<T> from scratch without inheriting AbstractList<T>, and the class would work in the same way.
AbstractList<T> is intended as a base class for other implementations of List<T>. Instead of establishing an interface, it follows an existing one. AbstractList<T>'s implementation of List<T> is not required, everything would compile and run without it just the same. However, inheriting List<T> lets Java compiler spot potential discrepancies between the interface methods and the methods of AbstractList<T>, so it is a very good idea for AbstractList<T> to implement List<T> interface.
I've just been reading through Java's documentation, and I'm wondering why their Queue implements both their Collection and their Iterable interfaces. Collection already implements the Iterable interface, so all of the abstract methods should pass through the Collection interface and reach the Queue Interface. What am I missing about their design here?
Nothing. The Javadoc Tool enumerates all of the implemented interfaces.
As we know, interfaces can extend interface in the Java. I have a question about this, if interface B extends interface A, B need not implement the methods defined in the A. But in the java.util package, the List interface extends Collection interface, and it implements the Collection method, these methods also just have the method declaration.
Why does it do this, and it there a better practice? Does it make any difference between implementing the method in the sub interface or not?
Overriding a method, besides providing/replacing a method implementation, allows to provide a more specific javadoc, and to narrow the return type.
For instance, Collection.iterator() is specified by:
Returns an iterator over the elements in this collection. There are no
guarantees concerning the order in which the elements are returned
(unless this collection is an instance of some class that provides a
guarantee).
while List.iterator() is specified by
Returns an iterator over the elements in this list in proper sequence.
I don't see any implementation in java.util.List but declarations. Instead the javadocs of List say,
The List interface places additional stipulations, beyond
those specified in the Collection interface, on the
contracts of the iterator, add, remove,
equals, and hashCode methods. Declarations for
other inherited methods are also included here for convenience.
The interface List do not implement Collections' methods because interfaces just cannot implement methods, they just declare them. An interface is like a 100% abstract class: all the methods must be abstract methods.
Probably your confusion comes from abstract classes that implement interfaces: these classes must not implement interface's methods (despite being allowed to), only the first concrete class must.
Interfaces are fully abstract in Java. They can't have any implementation.
Redeclaring a method is not the same as implementing it. And it doesn't make any sense to redeclare a method (if the method signature is exactly same), because the purpose of an interface extending another interface is to add some more-specific method declarations, and not to just redeclare the existing ones.
Edit
As pointed out in #Arham's and #meriton's answer, the purpose of the redeclaration is to respecify the method according to the sub-interface. So, for a client code, accessing the underlying collection, there would be a separate more-specific specification on the redeclared methods than the more-general one in the super-interface.
As Iterator is an interface with hasNext(), next() and remove() methods. But where is the implementation for all these methods in Java classes?
Almost every concrete collection has its own implementation, optimized for that specific collection. You don't have to bother about the details. But here are some examples:
LinkedList - class ListItr implements ListIterator<E>
ArrayList - class ListItr extends Itr implements ListIterator<E>
HashSet - actually backed by HashMap.keySet()
Becasue Iterator is an interface, you can do fancy things with it, like wrapping and decorating it, without paying attention to the actual implementation.
The Iterator interface is implemented as a inner and private (should be but not necessarily) class in the class/interface that implements the java.lang.Iterable<T> interface. The method of Iterable<T> - Iterator<T> iterator() allows an object to be the target of the "foreach" statement.
For more information read the blog of #Andreas Grech : Java's Iterators and Iterables