This question already has answers here:
Do interfaces inherit from Object class in java
(9 answers)
Closed 2 years ago.
I came across fact that Collection interface has methods equals and hashCode which are also contained in Object. Same is the case with List interface. I was having following doubts:
Why interfaces should have these methods? Is it only because they have different meaning than those in Object ?
According to this question, including these methods does not enforce the implementing class to provide their implementation as these implementations are already provided and inherited from Object. So technically including them in the interfaces does not have any effect. This again underlines importance of first doubt, why interfaces need to have these methods?
This page says:
These methods perform computations over the object’s state, but the interface, in general, has no access to state; only the implementing class has access to this state.
Which I feel further increases importance of first question.
If we at all need them in interfaces, then why Java framework dont have super-interface containing them and have such interfaces implement this interface, just like as all classes are subclasses of Object?
The List interface declares equals and hashCode so that it can document extra constraints that the implementations must follow. For example, the List interface documentation requires that the equals method must consider two lists equal if the have the same items in the same order, no matter how the lists are implemented.
There is no way the compiler or runtime can enforce these requirements, so breaking them leads to runtime bugs that may be hard to find.
Related
This question already has answers here:
Do Collections.unmodifiableXXX methods violate LSP? [closed]
(4 answers)
Closed 6 years ago.
Arrays.asList(..) returns a List wrapper around an array. This wrapper has a fixed size and is directly backed by the array, and as such calls to add() or other functions that attempt to modify the list will throw an UnsupportedOperationException.
Developers are often surprised by this, as is evident from questions in stackoverflow.
However the List interface has an add() method which should work unsurprisingly for all derivers of List, according to the Liskov Substitution Principle (LSP)
Is the type returned by Arrays.asList() an example of a violation of the Liskov Substitution Principle?
Strictly speaking, it is, because LSP has no notion of optional interface members: a method is either part of an interface, or it is not part of an interface.
However, Java Class Library explicitly allows for violations of LSP when it designates certain interface methods as optional. List<T>.add() is one such method. Other mutating methods (addAll, remove, etc.) are also marked optional.
Essentially, designers of Java library took a shortcut: rather than making a separate interface for mutable list (extending a read-only list) they went for designating an operation "optional". Moreover, they have not provided a way for you to test the instance of list for being read-only, so your only option is to catch a runtime exception, which is a very bad idea. This amounts to you having to keep track of where your lists came from, and performing optional operations only when you are 100% certain of your list origin.
I think it is not a violation of LSP.
LSP says that all instances of classes implementing a given interface can be used interchangably.
The documentation of List.add (and other mutating methods) clearly states that an UnsupportedOperationException might be thrown by implementations of that method.
Throws
UnsupportedOperationException - if the add operation is not supported by this list
As such, if you're going to invoke this method on an instance of List from an unknown source, you need to handle the case that add throws an UnsupportedOperationException.
If you don't, you're not using the API correctly.
This is not to say that I like the design. I think the fact that trying to invoke the method is the only way to detect that any given method is not supported on an instance is rubbish. I mean, heck, give us an isAddSupported() method (or similar).
I just don't see that following documented behaviour can be violating LSP.
If you think about it in very technical terms, then of course it is a violation. LSP states that a bad design is one in which the inherited class cannot use superclass methods. Java though, doesn't always care for violations. This is often, as you suggested, a way for confusion among developers. The add() method is one example, so is remove(). Both of these are available for an immutable list, and that cannot be changed. The good thing is that at least an exception is thrown.
Further reading: http://c2.com/cgi/wiki?UnmodifiableListIsStupidAndItBreaksLsp
This question already has answers here:
What is the "default" implementation of method defined in an Interface?
(3 answers)
Closed 6 years ago.
I was studying lambada and there was a point which states that in java 8 we can declare a method with definition in interfaces like
interface Test {
default String method(){
return "string";
}
}
and as per specification we can use two methods with same signature but depends on programmer how he wants to use it?
Now the question is same task can be if achieved by using definition not declaration then what's the point of using default method?
like they behave same as regular method definition and programmer need to declare body and rest part?
what is the actual point as it seems a bit hard to grasp
thanks #ElliottFrisch and #kagemusha for hint after searching i got the answer
Why default methods?
List<?> list = …
list.forEach(…); // lambda code goes here
The forEach isn’t declared by java.util.List nor the java.util.Collection interface yet. One obvious solution would be to just add the new method to the existing interface and provide the implementation where required in the JDK. However, once published, it is impossible to add methods to an interface without breaking the existing implementation.
So it’d be really frustrating if we have lambdas in Java 8 but couldn’t use those with the standard collections library since backwards compatibility can’t be sacrificed.
Due to the problem described above a new concept was introduced. Virtual extension methods, or, as they are often called, defender methods, can now be added to interfaces providing a default implementation of the declared behavior.
Simply speaking, interfaces in Java can now implement methods. The benefit that default methods bring is that now it’s possible to add a new default method to the interface and it doesn’t break the implementations.
It doesn’t seem to be the language feature that would be appropriate to use every day, but it seems to be essential for Java Collections API update to be able to use lambdas naturally.
This question already has answers here:
When to use: Java 8+ interface default method, vs. abstract method
(16 answers)
Closed 7 years ago.
Why We need Defender methods in interfaces in java 8 as we already have abstract classes.I found various answers on internet like:
To add external functionality
But Abstract class is for partial Abstraction where as our interface is actually a pure abstract class so why their is a default method inside an interface?
The problem with sharing functionality by placing it in an abstract base class is that a class can derive from exactly one base class. This is a limitation in cases when you would like to inherit functionality from more than one base.
Sharing functionality through an abstract base class may also become a problem when you need to implement an interface from a class that already has a base class. In this case you cannot derive your new class at all, because you must pick one of the two bases, when presumably you want both.
Default methods solve this problem with elegance: placing your common implementation into the default method allows you to share the code without limitations.
You can think of the main difference between default methods and inheriting an abstract class as the difference between sharing functionality horizontally across siblings that implement the same interface, or vertically among children that inherit from the same base class.
Here is an examoke: consider an interface that looks like ResultSet of JDBC, which has two ways of accessing the same column - by name and by index. The interface could be coded up like this:
interface ResultSet2 {
int findColumn(String columnLabel);
String getString(int index);
long getLong(int index);
default long getLong(String columnLabel) {
return getLong(findColumn(columnLabel));
}
default String getString(String columnLabel) {
return getString(findColumn(columnLabel));
}
}
Anyone implementing ResultSet2 would have to implement three methods, and get the remaining two for free. They would have an option to provide an alternative implementation, but that would be optional.
The main reason behind defender methods is to be able to extend long-existing interfaces with new functionality, without breaking the existing code. Particulary with Java 8 lamba expressions they introduced a lot of new methods on collection interfaces, like Iterable.forEach. With providing default methods, existing classes implementing the Iterable interface dont have to be altered to use in Java 8 environment.
The original intent was to compete with C#'s extension methods. Given core methods of an interface, e.g. get(), set() in List, extention methods (e.g. sort()) can be defined and implemented.
Java guys argued that it would be better to declare such methods on the interface itself, rather than in external places; so that the methods could be overridden by subtypes, providing optimal implementations per subtype. (They also argued that such methods should be controlled by the interface authors; this is rather a soft point)
While default methods can be added to existing interfaces, it is very risky of breaking existing 3rd party subtypes, particularly for very old types like List with lots of subtypes in the wild. Therefore very few default methods were added to existing core Java APIs. See this question.
For new interfaces, default method is a very valuable tool for API designers. You can add a lot of convenience methods to an interface, for example, Function.compose(). Subtypes only need to implement abstract/core methods, not default methods (but they can if they want to).
I disagree with the idea that default methods can "evolve" interfaces. They do not change the core semantics of an interface, they are just convenience methods (in the form of instance method).
And default methods should be carefully designed up-front when the interface is designed; as said, it is very risky to add default methods afterwards.
C#'s extension method allows 3rd party to add convenience methods; this is very nice, and there is no reason why Java couldn't introduce something similar in future.
This question already has answers here:
Why there is no Hashable interface in Java
(2 answers)
Closed 9 years ago.
In Java, the Comparator interface allows a client to specify an equals() and compare() method for any type. A Comparator can be passed to most (or maybe all) collections that require sorting, and the methods in the Comparator will be used instead of the methods of the specified class. This allows clients to sort objects in a way that is different from their natural ordering, or even to sort objects that don't have a natural ordering (i.e. don't implement Comparable).
Why isn't there a similar interface for hashing? It could specify two methods, hashCode() and equals(), and be useful for HashSets or HashMaps in the same way Comparators are useful for sorting.
Edit: For those who marked this question a duplicate of this other question, I would mention that the other question asks why hashCode is included in every class instead of an interface, while this question is about abstracting the hashing function to allow multiple implementations of it.
Answer Edit: The best methods of getting this functionality seem to be:
-If you're ok using an external library and/or are already using Guava (which is a fantastic library for a lot of reasons), Guava has an Equivalence class that allows this.
-If you don't want to use an external library, you can use a custom built adapter, similar to what is done in the top answer on this SO question.
Questions of the form
"Why doesn't Java have XXX"
are difficult to answer objectively except with a generic
"We don't know because nobody here was in the room when the decision was made."
In this case:
On the face of it, this requirement can be implemented ... from a technical perspective.
This requirement has been proposed numerous times via RFEs. The most direct one is http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6435963. The RFE is marked as WONT FIX, though no particular reason is given.
This requirement could be, and has been adequately met by 3rd party libraries.
My reading of this is that it is not supported because it has not been deemed important enough for enough people that it needs to be supported. I'd say they made a reasonable call on that.
I also think that such an interface would be handy, specifically as a way to consider different kinds of equalities in collections. It should be similar to the way that you can make an object Comparable, but still override that behavior in a specific collection by providing some other Comparator.
As was pointed out in this question, Guava has an Equivalence class that provides a way to do this, by wrapping your class and letting you define at the wrapper level what 'equality' means in this context.
If your question is really why this didn't happen at language design time... well, hey, James Gosling and company are only human, right?
Hashing has really just one requirement: Being like a hash method. So you can implement it for a type without knowing who will use it in what way and for what purpose. So the hash method on the object itself is sufficient.
Equals on the other hand has different meanings in different contexts. For example you can sort people by first name, last name, age, size, weight, time of membership in a club ... So it makes sense to have different implementations of equal (and 'less than') for a single class.
Of course nothing keeps you from creating such an interface and using it ...
You can always change the hashcode() to say how the HashMap arranges your object in Map and improve its performence by implementing an effective hashcode method in your class.
How HashMap performs addition and removal from a hashed data is internal to HashMap and changing it would basically mean changing add,remove methods etc.
Also sorting is a common feature that is used more often and for a rare case when you really want to change how hashing happens in a map then there is always the option to extend a Map.
Let me try to say how I see it, why.
Briefly - you often need to sort a list objects, but you rare (if ever) need to cross compare identities of a list of object.
In Object, method hashCode is a secondary, helpful method, which main purpose is to serve the equals method. The agreement is that if for two objects hashCode returns different values, equals mustn't return true.
So, methods hashCode and equals serve to establish the identity of an object.
Method compareTo (in both Comparable and Comparator) serves another general purpose. It defines objects order, not their identity.
Resume - compareTo defines how the objects are ordered, hashCode (together with equals) defines objects identity.
Again - practice contribution is that you often have to sort a group of objects, but you rare (if ever) have to take a group of objects and cross compare their identities.
In Java to implement multiple inheritance we use interfaces. Is it the only use of interfaces? If yes, what is the main use of interface in Java? Why do we need interfaces in Java?
I would say the main use is polymorphism, or the ability to perform the same operation on a number of different objects. If different objects all implement the same interface and have the same method, you can store all of those objects in a Vector, for example, and iterate through the Vector calling that method on each one.
I was also thinking about how interfaces are used. I hope this will help others:
An interface is a contract (or a protocol, or a common understanding)
of what the classes can do. When a class implements a certain
interface, it promises to provide implementation to all the abstract
methods declared in the interface. Interface defines a set of common
behaviors. The classes implement the interface agree to these
behaviors and provide their own implementation to the behaviors. This
allows you to program at the interface, instead of the actual
implementation. One of the main usage of interface is provide a
communication contract between two objects. If you know a class
implements an interface, then you know that class contains concrete
implementations of the methods declared in that interface, and you are
guaranteed to be able to invoke these methods safely. In other words,
two objects can communicate based on the contract defined in the
interface, instead of their specific implementation.
Secondly, Java does not support multiple inheritance (whereas C++
does). Multiple inheritance permits you to derive a subclass from more
than one direct superclass. This poses a problem if two direct
superclasses have conflicting implementations. (Which one to follow in
the subclass?). However, multiple inheritance does have its place.
Java does this by permitting you to "implements" more than one
interfaces (but you can only "extends" from a single superclass).
Since interfaces contain only abstract methods without actual
implementation, no conflict can arise among the multiple interfaces.
(Interface can hold constants but is not recommended. If a subclass
implements two interfaces with conflicting constants, the compiler
will flag out a compilation error.)
from: http://www.ntu.edu.sg/home/ehchua/programming/java/J3b_OOPInheritancePolymorphism.html#zz-6.6
In addition to these responses I would say the most important use for interfaces is to reduce coupling between components in your software.
An interface allows to represent an agreement between classes on how they will talk to each other without being tied to the actual implementations.
This allows us to replace implementations by others (very useful for testing, or changing use cases) without changing the compiled code.
You need them so you can type your objects outside the hierarchy.
For example, the objects that can be compared can be pretty much anywhere on the object hierarchy - they do not need to have a common ancestor which can be compared. Strings can be compared, Integers can be compared, you could even make your own Frames that could be compared (say, a frame is "less" than another frame if it is more in the foreground - i.e. if it would overlay the other frame). Thus, if you want to refer to a thing that can be compared, you would be forced to declare a variable with the most general ancestor - in this case, Object. This is too general, because then it can also receive values which are not comparable (and would throw errors when you try to compare them).
Thus, the interface Comparable: it selects all the classes that implement the comparison functionality across the subclass-superclass hierarchy.
We need interfaces :
To achieve total abstraction.
To achieve security.
Java doesn't allow multiple inheritance but it can be achieved by implementing multiples interfaces.
Some code won't compile without it.
For example, in:
for (String name : list)
{
System.out.print("\nIn foreach loop: name: " + name);
}
list must implement the java.lang.Iterable interface.