I am reading the Java documentation about interfaces and reached the chapter about default methods. As far as I understand, when you define an interface and later add methods to it, all classes that implement this interface will break and are in need of implementing the new method.
So the documentation briefly mentions static methods as an option to mitigate this problem, but also states, that they would be viewed as "utility methods" and not essential:
If they add them as static methods, then programmers would regard them as utility methods, not as essential, core methods.
Why is this the case / why would they be viewed as "not essential"?
static methods do not work on the instance of a class, but are part of the class itself. They are most often used for utility type of tasks and therefor a little bit contradict object-orientation so should be used sparsely.
But, default methods != static methods. The docs just mention the static methods there to show how before default methods something could have been added to an interface without breaking all implementations.
Default methods are another way to add functionality to an interface without breaking existing impementations by specifying a default implementation for that method (even if it is just a throw new NotImplementedException()). And these methods can be implemented by the concrete classes that implemented this interface to provide the actual functionality they are meant for and thus overriding the default implementation of the method.
With static methods this is not possible, as they belong to the class object, not the instance and thus cannot be overridden by subclasses or implementations.
Because you call static methods generally on class not on the Interface, eg:
Integer.parseInt(); - is called on concrete class Integer
Because static methods are self-contained, they don't depend on other methods in an interface. And more over most of the static methods in java code are actually utility methods.
Related
I've been reading through some questions here on SO concerning the use of #Override in Java. (e.g. this one on override and this one on default methods, and obviously the documentations) However, I am still confused.
I was taught to always use and implement an interface when all behaviour in that interface needed to be used by a class. I get that. But as I was taught, you would do something like this (partially taken from the docs):
public interface TimeClient {
void setTime(int hour, int minute, int second);
}
Which is then implemented by a class.
public class TestSimpleTimeClient implements TimeClient {
public static void main(String[] args) {
}
#Override
public void setTime(int hour, int minute, int second) {
System.out.println(hour + " " + minute + " " +second);
}
}
The thing that bugs me is the implementation of the method in the interface. It doesn't do anything, it's only declared as a method that take arguments but doesn't do anything else. Then you take that method and Override it in a class that implements that interface.
I understand that this is a way to "force" classes to implement a method but I don't see how this is useful in some specific use cases.
Let's say I have an interface that's implemented by a couple of classes. I want most of these classes to share the same implementation of the method, but not all. The logical, and character-efficient way would be to have a way to say: these classes take the default method in the interface, but these classes override the default method. How would I go about doing that? Should the one that overrides the method only implement it, whereas the ones that simply use the default method as a whole extend it? And what if you only want this behaviour for a specific method in an interface?
The thing that bugs me is the implementation of the method in the interface. It doesn't do anything, it's only declared as a method that take arguments but doesn't do anything else.
That is not an "implementation of the method in the interface". That's just an interface method declaration. In programming, terminology matters. Interfaces tend to be devoid of any implementations. (Unless you are talking about the default interface methods of Java 8, but from the rest of your question it is unclear whether you are aware of their existence.)
I understand that this is a way to "force" classes to implement a class
A class cannot implement a class. A class extends a class. But a class implements an interface. In programming, terminology matters a lot.
It is not just a way to force classes to provide an implementation. It is also a way for callers to be able to invoke an interface method without having to know anything about the class that implements it.
but I don't see how this is useful in some specific use cases.
Well, take for example the Collection<T> interface, and the contains() method, which is implemented by a myriad of classes, among which ArrayList<T>, LinkedList<T>, HashSet<T>, BoundedBlockingQueue<T>, and so on, and so forth. Your code may look like this:
boolean hasPekingese( Collection<Animal> animals )
{
return animals.contains( AllOfMyAnimals.PEKINGESE );
}
Note how the hasPekingese() method does not have to know the exact class that is implementing Collection<Animal>. Which means that you may invoke hasPekingese() from a class which keeps its animals in an ArrayList<Animal>, and you may also invoke hasPekingese() from a class which keeps its animals in a BoundedBlockingQueue<Animal>. The method hasPekingese() does not know, and does not care.
Let's say I have an interface that's shared by a couple of classes.
It is unclear what you mean by "shared". Do you mean "implemented"? In programming, terminology is of paramount importance.
I want most of these classes to share the same implementation of the method, but not all. The logical, and character-efficient way would be to have a way to say: these classes take the default method in the interface, but these classes override the default method. How would I go about doing that?
There are many ways to go about that, the most common being to have some of these classes extend some common base class, which provides the common implementation of your method, so that the derived classes inherit this method, so they do not have to implement it. The rest of the classes do not extend that common base class, so each one of them has to provide its own implementations of that method.
Should the one that overrides the method only implement it, whereas the ones that simply use the default method as a whole extend it?
That's not clear. Also, please do not call it a "default method", because as of Java 8 "default method" is a term that has a very specific meaning, and although it is related to this discussion, it is different from the sense in which you are using it.
And what if you only want this behaviour for a specific method in an interface?
If a derived class wants the method to work differently, it may re-override it. Or, you may have two different base classes, one which implements the method in a certain way, and another which implements it differently, so half of your derived classes extend the first base class, while the other half of your derived classes extend the second base class.
Interfaces are like APIs. When some provider give you interface like List you don't think about if it is an ArrayList or other implementation, you just know what you can do with this object. Why? Because when you give an interface, you can change the implementation later, and don't worry that other part of code, that is using object through interface, will need changes.
I suppose that you think about things that should plug some behaviour to current class. These things can be called Traits in other programming languages, in another you have multiple inheritance. If you want some implemented logic that is propagated to your classes, you should use abstract classes in java with proper hierarchic. Remember that you can expand classes with inheritance or composition (open-closed principle).
Default methods in Interfaces (Java 8) can be tricky, because they cannot change state of the object. They might be some stubs or mathematics equation that only work with local and static context.
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.
What is best practice in Java 8 when I need a bunch of stateless utility methods. Is it right to have an interface that will not be implemented by anyone i.e. public interface Signatures and public interface Environments, or is it better to do it the old way - have public final class Signatures and public final class Environments with private constructors || enums?
The main purpose of interfaces is to provide a type and a vocabulary of operations (methods) on that type. They're useful and flexible because they allow multiple implementations, and indeed they are designed to allow implementations that are otherwise unrelated in the class hierarchy.
The question asks,
Is it right to have an interface that will not be implemented by anyone...?
This seems to me to cut against the grain of interfaces. One would have to look around the API to determine that there are no classes that implement this interface, and that there are no producers or consumers of this interface. Somebody might be confused and try to create an implementation of the interface, but of course they wouldn't get very far. While it's possible to have a "utility interface" with all static methods, this isn't as clear as the old unconstructible final class idiom. The advantage of the latter is that the class can enforce that no instances can ever be created.
If you look at the new Java 8 APIs, you'll see that the final class idiom is still used despite the ability to add static methods on interfaces.
Static methods on interfaces have been used for things like factory methods to create instances of those interfaces, or for utility methods that have general applicability across all instances of those interfaces. For example, see the Stream and Collector interfaces in java.util.stream. Each has static factories: Stream.of(), Stream.empty(), and Collector.of().
But also note that each has companion utility classes StreamSupport and Collectors. These are pure utility classes, containing only static methods. Arguably they could be merged into the corresponding interfaces, but that would clutter the interfaces, and would blur the relationship of the methods contained in the classes. For example, StreamSupport contains a family of related static methods that are all adapters between Spliterator and Stream. Merging these into Stream would probably make things confusing.
I would use the final class. Communicates to me better that it is a helper class with some utility methods. An interface definition is something I would expect to be implemented and the methods to be there to assist someone implement the interface.
In a good object oriented design, there are not many (if any) stateless utility methods.
The best technique I've come to deal with is to use state (Objects) to deal with the function.
So instead of doing
Temperature.farenheitFromCelcius(...);
I do
public class FarenheitFromCelcius implements Function<Celcius, Farenheit> {
public Farenheit apply(Celcius celcius) {
return new Farenheit(5 * celcius.getValue() / 9 + 32);
}
}
This has a few advantages. One being that it can be unloaded from memory much more easily. Another being that you can save on the number of type identifying interfaces, you can pass utility methods between methods, and a final being that you can leverage the Java type hierarchy.
The costs are minimal. Basically you have to alter how the method is applied.
public <T> R convertTemp(T temp, Function<T, R> conversion) {
return conversion.apply(temp);
}
Naturally you'd never write a full method to encapsulate an object oriented function, but I had to show an example...
Static methods in interfaces were added with two primary purposes:
In case of poor implementation in subclasses static interface methods can be used to provide checks (e.g. if a value is null).
Avoid using general utility classes (like Collections) and calling static methods through their proper interface.
So, it is a very good practice if you intend to share functionality to the corresponding classes.
update:
If you wish to build a pure collection of functions then you may want to use the abstract class with static methods and a private constructor.
in your case I would go for the final class instead of getting the fatigue that someone might implement or inherent this. For use-cases where you want a static util interface. I guess we need a final interface for that...
public final class Util {
private Util {
throw new AssertionError("Please don't invoke me");
}
public static someUtilMethod() {}
private static someHelperUtilMethod() {}
}
Java 8 interface default methods vs. non-abstract methods in abstract classes
- are there any differences between the two (besides the differences of iface - class, visibility etc.)
Isn't a default method a step back in Java, meaning it's against the essence that Java has advertised for years?!
non-abstract methods in abstract classes will be called when it's concrete subclass calls super() if it is overridden. So there are multiple possibilities. If method is not overridden then the super class method will be executed. if we use super() in the concrete subclass method then the overridden method with the super class method will be executed.
Where as Java 8 interface default methods are completely different. It provided a choice to the developers to implement the method in the implementing class or not. If the function is not implemented then and only then the default method will be executed.
Possible Use Case :
The most important use case for this new feature in the JDK libraries is the possibility to extend existing interfaces without breaking existing implementers: adding a new abstract method to an interface would require all implementing classes to implement that new method.(Source)
The important thing to keep in mind is that default methods don't have access to state, only to behaviour. It is actually a great place to define reasonable, default, behaviour.
Imagine you have an interface:
public interface Plant {
enum Pace { FAST, SLOW; }
void grow(Pace pace);
void growFast();
void growSlow();
}
It seems reasonable to provide a default behaviour:
default void growFast() { grow(Pace.FAST); }
default void growSlow() { grow(Pace.SLOW); }
This is a simplistic example but shows how default methods can be helpful. In this case, the way growSlow or growFast behaves is part of the interface contract so it makes sense to define their behaviour at the interface level.
However the interface makes no assumption about how the action "grow a plant" is implemented. That could be defined in an abstract class.
Firstly Default methods allow you to add new methods to interface without breaking existing implementations.
Also take an example of Collections class which is a utility class for Collection interface right.
So using default methods we can now move all the utility methods as default implementation in the Collection itself, which will make more sense than making a separate class for such utilities.
Also you will be able to inherit methods from multiple interfaces, which could not have been done using plain abstract classes.
the big difference is that the constructor can possibly be run in an anonymous class, possibly with checked exceptions. this prevents anonymous classes being functional interfaces, and in turn makes them unavailable to use as the basis for a lambda expression.
The main differences are:
Java 8 default methods of interfaces are public, while non-abstract (concrete) methods of abstract classes can be defined as public, protected or private.
Lambda expressions got introduced in Java 8, to use lambda features we need default methods(to preserve backward compatibility), non-abstract methods of abstract classes can not serve the purpose.
We have a given REST interface:
POST /calculation
<data>abc</data>
This calculation can be implemented by different logical "calculators" depending on the server config.
We are now designing the Java interface that each calculator must implement. The interface will have a method for each REST service.
Given that all REST (and HTTP) calls are stateless, each method should be static. However you can't define static methods in Java interfaces. Is there a good workaround for this situation?
We could define the methods as non static and then just first create an instance of the calculator class. It just seems cleaner to indicate that the methods are stateless by using the static keyword in the interface.
Stateless doesn't mean static. Stateless means that the component doesn't rely on state. I say component, because the whole implementation of your interface is actually stateless - it will not have any member variables. So multiple instances of the implementation classes are perfectly OK. Especially if you have a context to manage them - Spring or EJB for example.
It seems to me that you want an interface with the methods declared as normal, and an implementing class, and then simply instantiate a single instance of this. There's no reason per se for the methods themselves to be static.
Why do you think the methods should be static? They surely could be, but that would limit you in terms of plugging in a different implementation later. If you are concerned about memory consumption or the like, using a Singleton would do the same as static for you, as you already said in the last paragraph of your question.
If none of classes implementing this interface does not need to change the implementation, use static method in interface as helper method.
You won't need any workaround with java 8 version.
Java 8 supports static methods in interface. Have a look at this documentation page.
Static Methods:
In addition to default methods, you can defineĀ static methodsĀ in interfaces. (A static method is a method that is associated with the class in which it is defined rather than with any object. Every instance of the class shares its static methods.)
This makes it easier for you to organize helper methods in your libraries; you can keep static methods specific to an interface in the same interface rather than in a separate class
Other solution to your problem is using Singleton as suggested in accepted answer.