The intention of the refactor is good. It takes verbosity out of implementors and bundle XYPosition-related methods to its own class, similar to what we do with parameter objets to avoid functions with a lot of paremeters. You are complying with the Interface Segregation Principle that states that clients should not know about methods they don't need or use.
But an interface (an abstraction) should not depend on a concretion (a non-abstract class). Both abstraction and concretions should depend on abstractions. This is called the Dependency Inversion Principle. Things that change less often (interfaces) should not depend on things that change more often (implementations) but the other way around. So my suggestion is that you make XYPosition an interface, then move the implementation to a concrete XYPosition class (choose another name).
java - why Interface Default methods? - Stack Overflow
Implementing two interfaces with two default methods of the same signature in Java 8 - Stack Overflow
Why would you use default methods in interfaces?
What is the purpose of default methods in Java Interfaces?
Videos
Before Java 8, interfaces could have only abstract methods. The implementation of these methods has to be provided in a separate class. So, if a new method is to be added in an interface then its implementation code has to be provided in the class implementing the same interface.
To overcome this issue, Java 8 has introduced the concept of default methods which allow the interfaces to have methods with implementation without affecting the classes that implement the interface.
The default methods were introduced to provide backward comparability so that existing interfaces can use the lambda expressions without implementing the methods in the implementation class. Default methods are also known as defender methods or virtual extension methods.
To overcome that we could have had one class providing implementation of these default methods and then implementing class like arraylist etc could have extended that.
Your suggestion would work only for standard JDK classes (since they usually extends some base classes such as AbstractCollection and AbstractList, were the implementation of the new methods can be added).
What about custom classes that implement JDK interfaces? If, for example, you have a class that implements List but doesn't extend some JDK List implementation, you should be able to switch to Java 8 without having to implement new methods in your class.
With default implementations of new methods in the List interface, you don't have to touch your custom class. You can later add a custom implementation to those methods if you are not satisfied by the default implementation.
This is a compile-time error. You cannot have two implementation from two interfaces.
However, it is correct, if you implement the getGreeting method in C1:
public class C1 implements I1, I2 // this will compile, bacause we have overridden getGreeting()
{
public static void main(String[] args)
{
System.out.println(new C1().getGreeting());
}
@Override public String getGreeting()
{
return "Good Evening!";
}
}
I just want to add that even if the method in I1 is abstract, and default in I2, you cannot implement both of them. So this is also a compile-time error:
public interface I1
{
String getGreeting();
}
public interface I2
{
default String getGreeting() {
return "Good afternoon!";
}
}
public class C1 implements I1, I2 // won't compile
{
public static void main(String[] args)
{
System.out.println(new C1().getGreeting());
}
}
This is not specific to the question. But, I still think that it adds some value to the context. As an addition to @toni77's answer, I would like to add that the default method can be invoked from an implementing class as shown below. In the below code, the default method getGreeting() from interface I1 is invoked from an overridden method:
public interface I1 {
default String getGreeting() {
return "Good Morning!";
}
}
public interface I2 {
default String getGreeting() {
return "Good Night!";
}
}
public class C1 implements I1, I2 {
@Override
public String getGreeting() {
return I1.super.getGreeting();
}
}
This feature has baffled me since it was released and I've not used it myself. However there is some code where I work which uses it, and I really don't understand why.
Have you ever used default methods in interfaces, and if so, why?