Can an interface method have a body?
Asked Answered
E

4

91

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() {
                       ^
Ehf answered 28/3, 2014 at 13:2 Comment(14)
it is giving error. Jdk 1.6Quigley
Thats impossible in JavaKare
Nope. Use an abstract class instead.Fuse
Java8 allows default method body for interfaces.Ammonify
Idea IDE doesn't complain about it?Ehf
Java 8, yes. Before that, no.Nappe
above code with not compile.Selfgovernment
Only in Java 8 default methods have been introduced. Before that No.Rexferd
@The-Guy-With-The-Hat: the OS is irrelevant. Unless you meant to say 'version of Java'Adel
Tagged java8 , default-implementationAdel
@The-Guy-With-The-Hat: ah. My mistake. You're reminding me why I prefer Python :)Adel
@TheGuywithTheHat The JRE which the IDE runs on is completely separate from the JDK which is used for applications.Generable
@TheGuywithTheHat But still, the IDE might run in Java 6 yet you can choose to compile and run your application in Java 7 or 8 or whatever you have installed. It's completely separate.Generable
@Generable Oh, okay. Sorry for the confusion.Bast
O
122

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 no ZoneId object corresponding to the given identifier. (As a result, you can simplify the method getZonedDateTime)

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

Odontoid answered 28/3, 2014 at 13:5 Comment(9)
Also default implementations of methods.Nappe
I am not using java 8. It is javac 1.7.0_25.Ehf
Is your IDE using code compliance 8? That should not compile with 7 and below. Here's a good article.Mongoloid
As per the article, check the new methods added to the Comparator interface in Java 8.Mongoloid
@Phoenix I am also using 1.7.0_25 version but it is not allowed in this versionSelfgovernment
Idea is configured to 1.7.0_25. But still it doesn't show compiler error. But at command line I am getting error.Ehf
This seems to really blur the lines between interfaces and abstract classes.Jehovist
@JeffGohlke See this question: #22591999Generable
"Everything about java 8" link has been changed or you have posted the wrong URL which will be a rare case. "Updated on "techempower.com/blog/2013/03/27/everything-about-java-8" 27th instead of 26th marchChillon
B
21

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.

Bast answered 28/3, 2014 at 13:24 Comment(0)
B
17

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.

Baillie answered 28/3, 2014 at 19:5 Comment(0)
S
2

Over the period java interfaces have evolved a lot and Java 8 completely changed the way interfaces were presumed.

Coming to question, yes we can have a method body in the interface.

whereas in java 8 we can have a method body in a static method and in the default method like the below example.

interface CheckMyEvolution{   
 default void whatsNew() {   
     System.out.print("Hello there!Check my Evolution");   
 } 

static 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();
    }
}
}

we can also have the private method in the interfaces from java 9 onwards. like below code compiles well in java 9 and above versions but fails in java 8 and below

interface CheckMyEvolution{   
     default void whatsNew() {   
         checkIt();   
     }   
     // Private method  
     private void checkIt() {   
         System.out.println("Hello there! I can have private method now. Make sure you are using JDK 9 or Above.");   
     }   
 }   
    public class CheckMyEvolutionImpl implements CheckMyEvolution{   
     public static void main(String[] args) {   
         CheckMyEvolution evolution= new CheckMyEvolutionImpl();   
         evolution.whatsNew();   
     } 
}   
 

References: https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html [https://www.quora.com/profile/Rajat-Singh-187/Private-Method-in-the-Java-Interface]

Sauls answered 15/7, 2022 at 9:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.