46

Why can't I create a @FunctionalInterface with a default method implementation?

@FunctionalInterface
public interface MyInterface {
    default boolean authorize(String value) {
        return true;
    }
}
Praveen Kumar Mekala
  • 628
  • 1
  • 10
  • 26
membersound
  • 81,582
  • 193
  • 585
  • 1,120

4 Answers4

55

You can have default methods in a functional interface but its contract requires you to provide one single abstract method (or SAM). Since a default method have an implementation, it's not abstract.

Conceptually, a functional interface has exactly one abstract method. Since default methods have an implementation, they are not abstract.

and

If a type is annotated with this annotation type, compilers are required to generate an error message unless:

The type is an interface type and not an annotation type, enum, or class.

The annotated type satisfies the requirements of a functional interface.

Here you don't satisfy the functional interface's requirement, so you need to provide one abstract method. For example:

@FunctionalInterface
interface MyInterface {

    boolean authorize(int val);
    
    default boolean authorize(String value) {
        return true;
    }
}

Note that if you declare an abstract method overriding one of a public method from the Object's class it doesn't count, because any implementation of this interface will have an implementation of those methods through at least the Object's class. For example:

@FunctionalInterface
interface MyInterface {

    default boolean authorize(String value) {
        return true;
    }

    boolean equals(Object o);
}

does not compile.

Community
  • 1
  • 1
Alexis C.
  • 91,686
  • 21
  • 171
  • 177
  • 1
    The last sentence is very misleading. You probably mean “abstract methods whose signature matches a method declared in `java.lang.Object`”. The important point is that the *declaration* in a concrete class has precedence, even if a subclass overrides it with an `abstract` method. That `abstract` method of a non-`interface` class still has precedence over `interface` methods, even if the latter are not `abstract`. – Holger May 11 '15 at 11:02
  • 1
    @Holger Yes this is what I meant. I updated it to make it more clear. – Alexis C. May 11 '15 at 11:12
  • @Holger, Seems to me that, `java.lang.Object` is _like_ an interface with some `default` methods – mjalil Nov 30 '21 at 06:34
  • 2
    @mjalil except that `default` methods can not be `protected` nor `final`. And, as already said, methods from a concrete class like `Object` have precedence over interface methods. – Holger Nov 30 '21 at 09:49
13

A functional interface is an interface having a single abstract method. The entire purpose of defining functional interfaces is to enable the implementation of the single abstract method via lambda expressions which will effectively override that method which makes providing a default implementation for it pointless.

Having an interface consisting entirely of default methods raises multiple problems. There is the technical problem that the compiler can’t decide for a lambda expression which method to implement when there are multiple default methods and there is the semantic problem that an interface consisting entirely of default methods is not abstract. You can’t instantiate this default behavior as you can’t instantiate interfaces and are forcing programmers to create concrete classes just to invoke the default behavior, which, since interfaces are stateless, could be provided by a singleton instead:

@FunctionalInterface
public interface MyInterface {
    static MyInterface DEFAULT = s->true;
    boolean authorize(String value);
}

Note that you can have interfaces extending a functional interface and providing a default method, if you need. Still, if this results in creating an interface having no abstract methods I would question the design. You may compare with the discussion about marker interfaces with default methods. If the sub-interface will have different abstract methods than the functional interface, it’s a different story. There might be real use cases for this, but these sub-interfaces will also demonstrate why they shouldn’t be mixed with the functional base interface as a lambda expression will always implement the abstract method.

Community
  • 1
  • 1
Holger
  • 285,553
  • 42
  • 434
  • 765
  • `default` methods in functional interfaces isn't pointless. It [can be used](https://stackoverflow.com/a/27252163/2377645) to handle checked exceptions for non throwing interfaces like `Supplier`. – Ivan Jan 28 '21 at 14:59
  • 1
    @Ivan you should try to read correctly before commenting. No-one said that default methods were pointless. Having *only* default methods would be pointless. You should read and understand the question first, as answers are given in that specific context. – Holger Jan 28 '21 at 15:02
8

That's because @FunctionalInterface can have default methods, as many as you want. For example, consider the java.util.Function interface. It contains two default methods: compose and andThen. But there should be exactly one non-default method. Otherwise how compiler would know which of your default methods should be mapped to lambda?

Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
-3

I just want to add a few more points.

  1. We can have any number of Abstract method in FuntionalInterface.

  2. We can also have any number of Static method in FuntionalInterface.

  3. We can also declare an abstract method overriding one of a public method from the Object's class but there must be some other custom abstract method in this functional interface too as shown in below code

    @FunctionalInterface public interface SAM { public void helloSam();

        default void xyz() {
            System.out.println("xyz");
        }
    
        static void abc() {
            System.out.println("abc");
        }
    
        static void abc1() {
            System.out.println("abc1");
        }
    
        default void xyz1() {
            System.out.println("xyz1");
        }
    
         boolean equals(Object o);
    }
    
Amandeep Rohila
  • 3,558
  • 2
  • 28
  • 34
  • Would having these method add some value or solve something? This isn't aligned with the purpose of functional interface which is to facilitate lambda expressions isn't it? – vbnr Jan 31 '20 at 08:57
  • 1
    We can have only one Abstract method in a FunctionalInterface. Point #1 is misleading – Vinod Akkepalli May 09 '20 at 14:21