Can an interface method have a body?
JavaInterfaceJava 8Default ImplementationJava Problem Overview
I know that an interface is like a 100% pure abstract class. So, it can't have method implementation in it. But, I saw a strange code. Can anyone explain it?
Code Snippet:
interface Whoa {
public static void doStuff() {
System.out.println("This is not default implementation");
}
}
EDIT:
My IDE is Intellij Idea 13.1. The project SDK is java 7 <1.7.0_25>. The IDE is not showing any compiler error. But, When I compile the code at command line I am getting the following message.
> Whoa.java:2: error: modifier static not allowed here > public static void doStuff() { > ^
Java Solutions
Solution 1 - Java
From Java 8 you can define static methods in interfaces in addition to default methods.
-
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.
-
The following example defines a static method that retrieves a
ZoneId
object corresponding to a time zone identifier; it uses the system default time zone if there is noZoneId
object corresponding to the given identifier. (As a result, you can simplify the methodgetZonedDateTime
)
Here is code :
public interface TimeClient {
// ...
static public ZoneId getZoneId (String zoneString) {
try {
return ZoneId.of(zoneString);
} catch (DateTimeException e) {
System.err.println("Invalid time zone: " + zoneString +"; using default time zone instead.");
return ZoneId.systemDefault();
}
}
default public ZonedDateTime getZonedDateTime(String zoneString) {
return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
}
}
See also
-
For all interesting things in Java 8 read Everything about Java 8
Solution 2 - Java
This is only possible in Java 8. In the Java 7 Language Specification §9.4, it explicitly states:
> It is a compile-time error if a method declared in an interface is declared static, because static methods cannot be abstract.
So in Java 7, static methods in interfaces cannot exist.
If you go to the Java 8 Language Specification §9.4.3, you can see that it says:
> A static method also has a block body, which provides the implementation of the method.
So it explicitly states that in Java 8, they can exist.
I even tried to run your exact code in Java 1.7.0_45, but it gave me the error "modifier static not allowed here".
Here is a quote directly from the Java 8 tutorial, Default Methods (Learning the Java Language > Interfaces and Inheritance):
> ## 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. The following example defines a static
> method that retrieves a ZoneId
object corresponding to a time
> zone identifier; it uses the system default time zone if there is no
> ZoneId
object corresponding to the given identifier. (As a result,
> you can simplify the method getZonedDateTime
):
>
> public interface TimeClient {
> // ...
> static public ZoneId getZoneId (String zoneString) {
> try {
> return ZoneId.of(zoneString);
> } catch (DateTimeException e) {
> System.err.println("Invalid time zone: " + zoneString +
> "; using default time zone instead.");
> return ZoneId.systemDefault();
> }
> }
>
> default public ZonedDateTime getZonedDateTime(String zoneString) {
> return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
> }
> }
>
> Like static methods in classes, you specify that a method definition
> in an interface is a static method with the static
keyword at the
> beginning of the method signature. All method declarations in an
> interface, including static methods, are implicitly public
, so you
> can omit the public
modifier.
Solution 3 - Java
For java version 7 or below, similar functionally you can achieve using nested class declared within interface body. and this nested class implements outer interface.
Example:
interface I1{
public void doSmth();
class DefaultRealizationClass implements I1{
@Override
public void doSmth() {
System.out.println("default realization");
}
}
}
How do we use it in our code?
class MyClass implements I1{
@Override
public void doSmth() {
new I1.DefaultRealizationClass().doSmth();
}
}
Therefore default implementation encapsulated within interface.