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.
Related
Why did new Spliterators class appear in Java 8? Since Java 8 we have possibility to add static methods to the interfaces.
Since Spliterators class has only static method wouldn't be simpler to declare all its methods in the Spliterator interface?
The same question about Collectors/Collector pair.
Thank you.
It’s perfectly possible that this decision was made without even thinking about this brand new possibility, but simply following the established-since-twenty-years pattern.
Besides that, it can be debated whether it is really useful to add 25 to 30 static methods to an interface. It makes sense to offer a few factories for canonical implementations, but you should draw a line somewhere. It’s not feasible to add factories to all implementations to an interface, just because they are offered by the same library. But this debate would be off-topic.
Further, Spliterators does not only offer static methods, but also nested classes. Unlike static methods, these classes would pollute the name space of every implementation class, when being defined in an interface.
Collectors and Spliterators may also contain implementation-specific non-public methods and even fields.
No, is not good idea, because interface declares a contract, but class represents logic. But after add default method to interface in Java 8 we can only declare public method, but in abstract class we can add public and private abstract method, so we still can hide some logic in abstract classes. Imagine, in actual level of language you can declare only public method, and everyone can change your idea for e.q. Collection
Because there is a difference between an interface and a class. These two have different intentions. Interface declares a contract. Default methods for the interface should be used carefully, for instance, where you can't break compatibility by adding a method declaration into an interface and can't declare xxxV2 interface.
A class is an entity, which represents a unit of the program logic.
In programming language, if you want that a child object should act as a substitute to parent & still it should not loose its own identity (of being child), you must have parent's permission. And that is why we make such methods virtual in C# or C++. And this becomes a complete hiding. Is the complete hiding considered as overriding in java? 99% of time I have wrong concept here because I think I am considering it only hiding. Can an overriden function be a complete hiding as fas as only JAVA is concerned?
Liskkiov's principle of substitution is linked to a function returning an abstract parent implementation instead of concrete child implementation. For example
ArrayList getList vs List getList
In the above example in the first case the getList method returns a concrete List implementation and in the second case the getList method returns an instance of the List interface. Now as per Liskov principle of substitution the second approach should be used as the second method can be overriden by subclasses to return different concrete implementations of List while in the first instance only an ArrayList of sub classes of ArrayList can be returned. So the first case is less abstract than the second case and as per Liskov's substitution principle the parent implementation should be as abstract as possible to allow the child to implement as freely as required.
Regarding method hiding so that is only possible with static methods. Overriding in java does not hide the method since its at instance level. However for static methods, since the method is at class level, polymorphism is not possible , and thus while they are inherited if a sub class creates a static method with the same name,arguments and return type and tries to access the method statically the sub classes version would be called and not the super classes version as the sub class has now effictively hidden the method from the super class.
I think it might, because the Comparator interface contains an equals method.
From section 9.2 of the Java Language Specification:
If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface. It is a compile-time error if the interface explicitly declares such a method m in the case where m is declared to be final in Object.
This allows you to call any of the Object methods via a reference of an interface type - which makes sense, given that the implementation will certainly be a subclass of Object.
EDIT: In the case of Comparator, it so happens that equals is explicitly redeclared, in order to provide more documentation. However, you'd be able to call equals on a Comparator reference anyway.
No interface implements Object class but the implementation does
In Java, every class will ultimately extend Object. While you can't instanciate Comparator itself, all comparator implementations will still extend Object.
The equals() method is redeclared in Comparator in order to adapt the Javadoc for the special contract that Comparator imposes on equals()
No interfaces ever extends/inherit an Object. Only it's implemented classes does extends Object implicitly (if not explicitly extended).
The Comparator.equals() method follows the same signature as Object.equals() method. The reason for this is stated on the JavaDoc:
However, overriding this method may,
in some cases, improve performance by
allowing programs to determine that
two distinct comparators impose the
same order.
Interface types are not officially subtypes of Object, but behave as if they were:
They also implicitly declare all the methods of Object (as quoted by Jon)
They can be converted to Object by an widening conversion without an explicit cast
All objects of the interface type are automatically objects of the object type
In this case, the interface type redeclares the equals method in a compatible way, and the implementation from Object is used if the implementing class does not provide its own implementation.
The specification here is done in a way that the default implementation from Object.equals also fits the specification of Comparator.equals, and that every (conformant) implementation of Comparator.equals also fits the specification of Object.equals.
Please refer below link
http://www.docjar.com/html/api/java/util/Comparator.java.html
You can see in the code that Comparator interface has its own equals method.
In java, an interface can never be created by inheriting it from a class. So, no, Comparator interface doesn't inherit Object class.
The interfaces are like Roles and its responsibilities are declared as interface methods.
Comparator being the interface just lists all the responsibilities which needs to be provided by a class which implements this interface.
The object of the class which implements Comparator will be subclass of the Object class.
Why do many Collection classes in Java extend the Abstract class and also implement the interface (which is also implemented by the given abstract class)?
For example, class HashSet extends AbstractSet and also implements Set, but AbstractSet already implements Set.
It's a way to remember that this class really implements that interface.
It won't have any bad effect and it can help to understand the code without going through the complete hierarchy of the given class.
From the perspective of the type system the classes wouldn't be any different if they didn't implement the interface again, since the abstract base classes already implement them.
That much is true.
The reason they do implement it anyways is (probably) mostly documentation: a HashSet is-a Set. And that is made explicit by adding implements Set to the end, although it's not strictly necessary.
Note that the difference is actually observable using reflection, but I'd be hard-pressed to produce some code that would break if HashSet didn't implement Set directly.
This may not matter much in practice, but I wanted to clarify that explicitly implementing an interface is not exactly the same as implementing it by inheritance. The difference is present in compiled class files and visible via reflection. E.g.,
for (Class<?> c : ArrayList.class.getInterfaces())
System.out.println(c);
The output shows only the interfaces explicitly implemented by ArrayList, in the order they were written in the source, which [on my Java version] is:
interface java.util.List
interface java.util.RandomAccess
interface java.lang.Cloneable
interface java.io.Serializable
The output does not include interfaces implemented by superclasses, or interfaces that are superinterfaces of those which are included. In particular, Iterable and Collection are missing from the above, even though ArrayList implements them implicitly. To find them you have to recursively iterate the class hierarchy.
It would be unfortunate if some code out there uses reflection and depends on interfaces being explicitly implemented, but it is possible, so the maintainers of the collections library may be reluctant to change it now, even if they wanted to. (There is an observation termed Hyrum's Law: "With a sufficient number of users of an API, it does not matter what you promise in the contract; all observable behaviors of your system will be depended on by somebody".)
Fortunately this difference does not affect the type system. The expressions new ArrayList<>() instanceof Iterable and Iterable.class.isAssignableFrom(ArrayList.class) still evaluate to true.
Unlike Colin Hebert, I don't buy that people who were writing that cared about readability. (Everyone who thinks standard Java libraries were written by impeccable gods, should take look it their sources. First time I did this I was horrified by code formatting and numerous copy-pasted blocks.)
My bet is it was late, they were tired and didn't care either way.
From the "Effective Java" by Joshua Bloch:
You can combine the advantages of interfaces and abstract classes by adding an abstract skeletal implementation class to go with an interface.
The interface defines the type, perhaps providing some default methods, while the skeletal class implements the remaining non-primitive interface methods atop the primitive interface methods. Extending a skeletal implementation takes most of the work out of implementing an interface. This is the Template Method pattern.
By convention, skeletal implementation classes are called AbstractInterface where Interface is the name of the interface they implement. For example:
AbstractCollection
AbstractSet
AbstractList
AbstractMap
I also believe it is for clarity. The Java Collections framework has quite a hierarchy of interfaces that defines the different types of collection. It starts with the Collection interface then extended by three main subinterfaces Set, List and Queue. There is also SortedSet extending Set and BlockingQueue extending Queue.
Now, concrete classes implementing them is more understandable if they explicitly state which interface in the heirarchy it is implementing even though it may look redundant at times. As you mentioned, a class like HashSet implements Set but a class like TreeSet though it also extends AbstractSet implements SortedSet instead which is more specific than just Set. HashSet may look redundant but TreeSet is not because it requires to implement SortedSet. Still, both classes are concrete implementations and would be more understandable if both follow certain convention in their declaration.
There are even classes that implement more than one collection type like LinkedList which implements both List and Queue. However, there is one class at least that is a bit 'unconventional', the PriorityQueue. It extends AbstractQueue but doesn't explicitly implement Queue. Don't ask me why. :)
(reference is from Java 5 API)
Too late for answer?
I am taking a guess to validate my answer. Assume following code
HashMap extends AbstractMap (does not implement Map)
AbstractMap implements Map
Now Imagine some random guy came, Changed implements Map to some java.util.Map1 with exactly same set of methods as Map
In this situation there won't be any compilation error and jdk gets compiled (off course test will fail and catch this).
Now any client using HashMap as Map m= new HashMap() will start failing. This is much downstream.
Since both AbstractMap, Map etc comes from same product, hence this argument appears childish (which in all probability is. or may be not.), but think of a project where base class comes from a different jar/third party library etc. Then third party/different team can change their base implementation.
By implementing the "interface" in the Child class, as well, developer's try to make the class self sufficient, API breakage proof.
In my view,when a class implements an interface it has to implement all methods present in it(as by default they are public and abstract methods in an interface).
If we don't want to implement all methods of interface,it must be an abstract class.
So here if some methods are already implemented in some abstract class implementing particular interface and we have to extend functionality for other methods that have been unimplemented,we will need to implement original interface in our class again to get those remaining set of methods.It help in maintaining the contractual rules laid down by an interface.
It will result in rework if were to implement only interface and again overriding all methods with method definitions in our class.
I suppose there might be a different way to handle members of the set, the interface, even when supplying the default operation implementation does not serve as a one-size-fits-all. A circular Queue vs. LIFO Queue might both implement the same interface, but their specific operations will be implemented differently, right?
If you only had an abstract class you couldn't make a class of your own which inherits from another class too.
This question already has answers here:
When to use an interface instead of an abstract class and vice versa?
(26 answers)
Closed 5 years ago.
In Java, you can create an abstract class that contains only abstract methods. On the other hand, you can create an interface that declares the same methods. That being the case, can you use abstract classes instead of interfaces?
Not always:
a class can extend only one class
a class can implement more than one interface
Sun docs make a more detailed comparison:
Abstract Classes versus Interfaces
Unlike interfaces, abstract classes can contain fields that are not static and final, and they can contain implemented methods. Such abstract classes are similar to interfaces, except that they provide a partial implementation, leaving it to subclasses to complete the implementation. If an abstract class contains only abstract method declarations, it should be declared as an interface instead.
Multiple interfaces can be implemented by classes anywhere in the class hierarchy, whether or not they are related to one another in any way. Think of Comparable or Cloneable, for example.
By comparison, abstract classes are most commonly subclassed to share pieces of implementation. A single abstract class is subclassed by similar classes that have a lot in common (the implemented parts of the abstract class), but also have some differences (the abstract methods).
In some cases you can use an abstract class instead of interface. However, it is hardly ever a good idea to do so. In general you should use the rule:
Interfaces specify behaviour.
Abstract classes specify implementation.
The other "problem" with using abstract classes is that you can then no longer implement mixins, that is you can implement multiple interfaces, however you can only extend one abstract class.
One point missing from the answers here is the idea of who will be implementing the interface.
If your component wants to return instances of abstract types to its callers, where the concrete types are defined internally and hidden from callers, use an interface. Conversely, if your component consumes or accepts instances of abstract types that its callers must implement, abstract classes are usually a better choice.
Anticipating evolution and maintaining binary compatibility tips the scales here. With an abstract class, you can add methods and, if you provide a base implementation, existing implementations of the abstract class will continue to work fine. With an interface, adding a method breaks binary compatibility, for no existing implementation could possibly continue to compile properly without changing to define the new method.
The Apache Cactus project has a good discussion on how to resolve these obligations.
To answer your question, yes you could use an abstract class (providing no implementation) instead of an interface but I'd consider this bad practice:
You've used up your "one-shot" at inheritance (without gaining any benefit).
You cannot inherit from multiple abstract classes but you can implement multiple interfaces.
I would advocate the use of abstract classes more in situations where you wish to provide a partial implementation of a class, possibly delegating some behavior to concrete subclass implementations.
A class in java can inherit from multiple interfaces, but only from one abstract class.
An interface cannot define any code, in an abstract class, you can define code (i.e. default behaviour of methods)
Abstract classes and interfaces are complementary.
For instance when creating an API you will want to present interfaces to the client, so that you may always completely change the implementation whereas he does not have to change its code and the user does not rely on implementation when building using your API but just on methods contracts.
Then you will have abstract classes partly implementing these interfaces, in order to
share some common code, which might be used in all (or almost all) implementations for interface, which is obvious
provide default behaviour which could be overridden in 'real' implementations, for instance a toString() method using interfaces methods to create a textual representation of the implementation
preserve implementations compatibility after interface changes, for instance when you add a new method in your interface, you also add a default implementation in the abstract class so that implementations (for instance those made by the user) extending the abstract class still work without changes
Interfaces are much cleaner and light weight. Abstract classes make you dependent on it heavily as you cannot extend any other classes.
Have a look at the interesting article "Why extends is evil" to get an idea about the differences between interface implementation and class inheritance (beside the obvious multi- single restrictions)
Abstract classes are the partial implementation of Abstraction while Interfaces are the fully implementation of Abstraction.Means in Abstract classes we can put methods declaration as well as method body.
We can't create an object of Abstract classes(association) and reuse the class by inheritence(not by association).
By default in interfaces all declared variables are static final and All methods are public.
For Example: In JDK there are only few abstract classes and HttpServlet is one of them which is used in Servlet.So we can't create object of HttpServlet and it can be used only by inheritence.
Main use of interface is when you create the reference of interface and call the method of particular class that's resolved at runtime. So it's always better idea to create reference of interface to call the method.
Interfaces can only hold abstract method, also interfaces can implement multiple interfaces to any class. But an abstract hold abstract and non abstract methods, and abstract methods cannot extend to more then one class.