This question already has answers here:
Purpose of Default or Defender methods in Java 8
(5 answers)
Closed 8 years ago.
I'm taking a look to Java 8 news compared to 7 and in addition to very interesting things like lambdas or the new time framework, i found that a new feature(?) was introduced: default methods.
I found the following example in this article:
public interface Math {
int add(int a, int b);
default int multiply(int a, int b) {
return a * b;
}
}
It seems very strange to me.
Above code looks like an abstract class with an implemented method. So, why to introduce default methods in an interface? What is the actual advantage of this approach?
In the same article I read this explaination:
Why would one want to add methods into Interfaces? We’ll it is because interfaces are too tightly coupled with their implementation classes. i.e. it is not possible to add a method in interface without breaking the implementor class. Once you add a method in interface, all its implemented classes must declare method body of this new method.
Well this doesn't convince me at all. IMHO I believe that when a class implements an interface obviosly must declare methods body for each method in it. This is surely a constraint, but it's also a confirm of its "nature" (if you understand what I mean...)
If you have common logic to every inheriting class you'll put it into an implementing abstract class.
So, what's the real advantage of a default method? (It looks more like a workaround than a new feature...)
UPDATE I understand that this approach is for backwards compatibility, but it still doesn't convince me so much. An interface represent a behaviour that a class MUST have. So a class implementing a certain interface has surely this behaviour. But if someone can arbitrarily change the interface, this constraint is broken. The behaviour can change anytime... Am I wrong?
This is for backwards compatibility.
If you have an interface that other people have implemented then if you add a new method to the interface all existing implementations are broken.
By adding a new method with a default implementation you remaining source-compatible with existing implementations.
For a slightly simple/contrived example that should hopefully demonstrate this let us say you created a library:
void drawSomething(Thing thing) {
}
interface Thing {
Color getColor();
Image getBackgroundImage();
}
Now you come to do a new version of your library and you want to add the concept of border colors, that's easy to add to the interface:
interface Thing {
Color getColor();
Color getBorderColor();
Image getBackgroundImage();
}
But the problem is that every single person using your library has to go back through every single Skin implementation they ever did and add this new method.
If instead you provided a default implementation to getBorderColor that just called getColor then everything "just works".
There have been a lot of methods acting on an abstract interface in the past. Before Java 8 they had to be put into an additional class pairing the interface, e.g. Collections with Collection.
This old approach was neither more convincing than default methods nor more practical. Instead of list.sort() you had to say Collections.sort(list). This also implies that you had to make a fundamental decision when creating an interface, either you require every List implementation to implement a sort method or you provide a sort method in a utility class that cannot be overridden.
With default methods you can have both, a standard implementation which the List implementations do not need to implement on its own but still can be overridden if a concrete implementation has a more efficient way to do it knowing its internals, e.g. ArrayList.sort passes its internal array directly to Arrays.sort skipping some intermediate operations.
Suppose at some point you want to add new functionality in declared interface, up to Java 7, If you will add a new method in declared an interface, you also have to define the implementation of the method in classes that are implementing that interface.
In java 8, You can add a default method containing the implementation and all the child class will inherit that method.
Edit : (After question update)
An interface represent a behaviour that a class MUST have
It still represent a behaviour that class must have, your confusion is how you are defining behaviour. All implementing class will inherit default method and are also free to write their own implementation. consider following two cases,
If implementing class does not provide own implementation and simply inherit default method. If you change behaviour of default method in interface, implementing classes will be having updated behaviour as they inherit default method so it holds An interface represent a behaviour that a class MUST have.
If implementing class provide own version of default method, and if you will change behaviour (only arguments) of default method. In this case implementing class will be having two overloaded methods, one which was earlier defined and second one is inherited default method. and if you change complete behaviour (arguments with return type also), It will create ambiguity in implementing class as you can not overload method by changing return type and Implementation will be broken. again it holds An interface represent a behaviour that a class MUST have.
Example :
Bulk data operation in collection is added in Java 8 (Reference : http://openjdk.java.net/jeps/107), to implement that forEach() method is added in Iterable interface. Adding abstract method in Iterable interface would break all the existing code because each class has to implement that method.
Solving the issue, following default forEach() method is added in Iterable interface,
interface Iterable
{
default void forEach(Consumer<? super T> action)
{
for (T t : this) action.accept(t);
}
}
Reference : Java 8 : Default method in Interface
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.
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.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
It is said, that Java language support single inheritance only.
However how is it possible to inherit from Object and from any other class at the same time? Isn't that a multiple inheritance.
Secondly, what for do we need to inherit all 11 Object methods? I could hardly imagine why do I need it them in I/O e.g.
Finally JDK 8 is going to offer us default methods realization in interfaces and if which would probably cause multiple inheritance in Java.
What if interface A provides method a() with default realization and interface B provides also a() method with another default realization and our custom class C implements both interfaces and rely on default realization - wouldn't that be Diamond of Death ?
However how is it possible to inherit from Object and from any other
class at the same time? Isn't that a multiple inheritance.
No this is not what happens. Not all classes directly extend from Object class. But only the class at the top level of inheritance hierarchy extends from Object class(implicitly). Rest of the classes lower in the hierarchy, extends from the Object class through the super classes. And, this is what we call multi-level inheritance.
So, consider the below hierarchy: -
class A { }
class B extends A { }
In the above case, class A is equivalent to class A extends Object.
Secondly, what for do we need to inherit all 11 Object methods? I
could hardly imagine why do I need it them in I/O
I suspect you meant override when you say inherit. You don't need to override any method of Object class. It's just on your requirement, whether to override any method or not. For e.g.: - You would often want to override equals() method, so as to write custom equality test for your instances. And in that case, you should also override the hashCode() method, to maintain the contract of equals() and hashCode().
Finally JDK 8 is going to offer us default methods realization in
interfaces and if which would probably cause multiple inheritance in
Java.
What if interface A provides method a() with default realization and
interface B provides also a() method with another default realization
and our custom class C implements both interfaces and rely on default
realization - wouldn't that be Diamond of Death ?
I can't comment on this concept, because I haven't read about this thing yet. Probably, I would update the answer sometime later.
However how is it possible to inherit from Object and from any other
class at the same time? Isn't that a multiple inheritance.
Unless otherwise specified, a class extends Object. That is, this:
class A { ... }
is equivalent to:
class A extends Object { ... }
Secondly, what for do we need to inherit all 11 Object methods? I
could hardly imagine why do I need it them in I/O e.g.
equals() and hashCode() are used in comparisons and hash tables.
notify() and wait() form the low-level basis of cross-thread communication.
getClass() is the starting point of all reflection code.
By putting them on Object, these can be used on every object in the JVM. You can get the hash code and the class of any object, you can check for equality between any two objects, you can monitor and notify any object.
What if interface A provides method a() with default realization and
interface B provides also a() method with another default realization
and our custom class C implements both interfaces and rely on default
realization - wouldn't that be Diamond of Death ?
As explained in another question here on SO (which is literally just one search for "jdk8 default methods" away):
To solve multiple inheritance issue a class implementing two
interfaces providing a default implementation for the same method name
and signature must provide an implementation of the method.
Thus, the class must provide its own implementation, possibly delegating to one of the default methods.
You are correct about "Diamond of Death" but ...
This is the situation where D implements interfaces C and B and both of those implement A. Further, there is a default method defined in two or more of those interfaces.
In Java 8 they defined a way that the two default method definitions are sorted out.
As I recall, if A and B both have a default method defined, then D uses B's version since it is lower in the class hierarchy.
If B and C both have the same default method defined then there is a conflict and D will need to implement the method itself though it can do so by calling back to the version implemented in either B or C (or it can have conditions and use both in different cases).
interface A { }
interface B implements A { void m() default {println("In A");} }
interface C implements A { void m() default {println("In B");} }
}
class D implements B, C {
public void m() { println("In D"); B.super.m(); }
}
But you can go to Oracle's pages about new features in Java 8 and read all about it. I got there by Googling "Java 8 new features". Found what I was thinking of at http://cr.openjdk.java.net/~briangoetz/lambda/Defender%20Methods%20v4.pdf
You inherit from a class, which inherits from object. Java does not allow you to inherit from two different class chains. However, the way around this is to use interfaces.
However how is it possible to inherit from Object and from any other
class at the same time?
You cannot do this, you heard wrong.
Secondly, what for do we need to inherit all 11 Object methods? I
could hardly imagine why do I need it them in I/O e.g.
Not sure what you're talking about here.
What if interface A provides method a() with default realization and
interface B provides also a() method with another default realization
and our custom class C implements both interfaces and rely on default
realization - wouldn't that be Diamond of Death ?
Don't know anything about JDK8, but you can already implement a method with the same name/type signature in two interfaces, which is probably illogical but Java allows it.
First- everything is an Object or a primitive in Java so you have no problems here. Object is the class on the top of the hierarchy.
At the moment you can apply multiple interfaces to Java already- then you write your realization. I would imagine that in Java 8- if you define your interface, then you have the realization. If not- then some default is used. If more than one default is defined (or the method is declared by more than one interface)- no default is used. It can be quite simple.
There is scenario where I have Interface X, which has been implemented with my thousands of classes. Now I want to add new method in that Interface X. So how to make the changes in minimal way to solve the problem of overridden of methods in all my classes
If the method implementation is common to all classes, maybe an abstract class is better then interface for it.
If it isn't - you are going to write these methods anyway.
(*)It was initially a comment, but I was requested to put it as an answer.
If your new method doesn't make sense for all implementations of that interface, don't add it there - make a new interface that extends your original one
If there should be a default implementation for all your thousand classes - change your interface to an abstract clas
Apart from the other suggestions (make it abstract or extend the interface) there is one further option:
Make all implementers of the interface extend a base class. This way, when you add methods to the interface you merely need to add default behaviour to the base class and class-specific behaviour to (hopefully) just a few implementers.
If you don't mind having no-op implementation of this method in all your classes and have control over all implementing classes, here is a very hacky way to do it with IntelliJ in 3 steps without going to each and every class:
Add your method to an interface
Select a method and invoke Refactor->Push Down... - your method declaration will appear in all the classes that implement this interface, but at least in my version of IntelliJ IDEA (11.0.2) they will have no implementation, e.g. void doSomething();, so select this definition and do a full-project Find & Replace to replace this string with your default implementation, for example,
#Override void doSomething() {}
Add your method to interface again.