Лямбда-выражение для создания экземпляра функционального интерфейса и переопределения одного и того же метода интерфейса по умолчанию в одном классе

// Базовый интерфейс — функциональный интерфейс, так как он содержит только один абстрактный метод

@FunctionalInterface
public interface BaseInterface {

    int sum(int a, int b);

}

Создание функционального интерфейса с использованием лямбда-выражения

public class Implementer {

    public static void main(String[] args) {
        BaseInterface base = (num1, num2) -> num1 + num2;

        System.out.println(base.sum(3, 2));
    }

}

Функциональность расширена в интерфейсе - добавлен новый метод по умолчанию

@FunctionalInterface
public interface BaseInterface {

    int sum(int a, int b);

    default String getUserDetails(String name) {
        return name;
    }   
}

Если я переопределяю метод по умолчанию, чтобы иметь конкретную реализацию, а не по умолчанию, необходимо использовать ключевое слово «реализует» для указания интерфейса следующим образом:

public class Implementer implements BaseInterface {

    public String getUserDetails(String uname) {
        uname = uname.trim();
        return uname;
    }

    public static void main(String[] args) {
        BaseInterface base = (num1, num2) -> num1 + num2;

        System.out.println(base.sum(3, 2));
    }

}

В этом случае компилятор выдает ошибку и предлагает реализовать унаследованные абстрактные методы. Итак, должен ли я в этом случае реализовать абстрактные методы обычным способом

public class Implementer implements BaseInterface {

    public String getUserDetails(String uname) {
        uname = uname.trim();
        return uname;
    }

    public static void main(String[] args) {
        //BaseInterface base = (num1, num2) -> num1 + num2;

        System.out.println(base.sum(3, 2));
    }

    @Override
    public int sum(int a, int b) {
        return a + b;
    }

}

(или) есть ли способ использовать лямбда-выражение?


person sake    schedule 12.02.2018    source источник
comment
Я думаю, что ссылки на методы (docs.oracle.com/javase/tutorial/java /javaOO/) может удовлетворить ваши требования. Обычно причиной использования лямбда-выражения является передача функции другой функции. Таким образом, вы все еще можете иметь тот же код и вызывать base::sum(3, 2). Если какой-то другой метод принимает параметр типа BaseInterface, вы можете отправить base::sum в качестве значения этому методу.   -  person William John Holden    schedule 12.02.2018
comment
Нет. Вы не можете переопределить отдельные методы, используя лямбда-синтаксис.   -  person shmosel    schedule 12.02.2018
comment
Что произойдет, если Implementer объявить как класс abstract?   -  person fps    schedule 12.02.2018
comment
@FedericoPeraltaSchaffner Создание класса как абстрактного не запрашивает. Я знаю, что абстрактный класс может абсолютно иметь неабстрактные методы, но является ли это хорошей практикой без неабстрактных методов, но при этом объявляя его абстрактным?   -  person sake    schedule 12.02.2018
comment
Сохраняя абстрактный класс Implementer, вы не реализуете метод sum, поэтому класс остается абстрактным. В любом случае, абсолютно нормально иметь абстрактный класс без абстрактных методов. Абстрактный класс представляет то, что вы не можете создать, но он не обязан содержать абстрактные методы.   -  person fps    schedule 12.02.2018


Ответы (1)


Вы можете переопределить метод по умолчанию в другом интерфейсе, который расширяет ваш BaseInterface:

public interface Extender extends BaseInterface {
    @Override
    default String getUserDetails(String uname) {
        uname = uname.trim();
        return uname;
    }
}

а потом Extender e = (a, b) -> 2 * a + 2 * b;

person Kirill Simonov    schedule 12.02.2018