Bridging multimethod interfaces to functional interfaces

Lamba expression autotyping only works on functional interfaces. A functional interface has a single abstract method. Being able to autotype other interfaces can be useful, but it doesn't come for free.

Here is an example of bridging a general Java interface with a pair of abstract methods to a functional interface so it can be used with Lambda expression autotyping:

package com.alainodea;

public class AddingMethodsToNonFunctionalInterface {
    public static void main(String[] args) {
        Square square = () -> 4;
        System.out.printf(showSquare(square));
        System.out.printf(showRectangle(square));
    }

    private static String showSquare(Square square) {
        return String.format("Square(length=%d, width=%d, height=%d)%n",
                square.length(), square.width(), square.height());
    }

    private static String showRectangle(Rectangle rectangle) {
        return String.format("Rectangle(width=%d, height=%d)%n",
                rectangle.width(), rectangle.height());
    }

    public interface Square extends Rectangle
    {
        int length();

        @Override
        default int width() {
            return length();
        }

        @Override
        default int height() {
            return length();
        }
    }
    public interface Rectangle {
        int width();
        int height();
    }
}

In this example we create a single subinterface that provides enough implementation via override default methods to become a functional interface itself.  From there it is possible to autotype to the subinterface and use the instance wherever the original interface was required.

The  Square subinterface provides an implementation of Rectangle where both width() and height() are defined in terms of a new abstract length() property.  When compiling Square square = () -> 4; Lamba Expression autotyping is able to infer that () -> 4 is the definition of length().

This is obviously a silly example, but you can reach for this technique any time you have to bridge a multimethod interface to a functional interface.