Интерфейсы Java 8 с методом по умолчанию: влияет ли это на множественное наследование? [Дубликат]

Единственный верный способ сохранить эти личные данные - сохранить их на своем сервере и отправить приложение на сервер, а сервер взаимодействует с Dropbox. Таким образом, вы НИКОГДА не распространяете свой закрытый ключ в любом формате.

30
задан Not a bug 27 March 2014 в 13:25
поделиться

5 ответов

Это ошибка времени компиляции. Вы не можете иметь две реализации из двух интерфейсов.

Однако, это правильно, если вы реализуете метод getGreeting в C1:

public class C1 implements I1, I2 // this will compile, bacause we have overridden getGreeting()
{
    public static void main(String[] args)
    {
        System.out.println(new C1().getGreeting());
    }

    @Override public String getGreeting()
    {
        return "Good Evening!";
    }
}

Я просто хочу добавить что даже если метод в I1 является абстрактным, а по умолчанию в I2, вы не можете реализовать оба из них. Таким образом, это также ошибка времени компиляции:

public interface I1
{
    String getGreeting();
}

public interface I2
{
    default String getGreeting() {
        return "Good afternoon!";
    }
}

public class C1 implements I1, I2 // won't compile
{
    public static void main(String[] args)
    {
        System.out.println(new C1().getGreeting());
    }
}
45
ответ дан kavai77 27 August 2018 в 03:13
поделиться

Если класс реализует 2 интерфейса, оба из которых имеют метод java-8 по умолчанию с одной и той же сигнатурой (как в вашем примере), класс реализации обязан переопределить метод . Класс по-прежнему может получить доступ к методу по умолчанию , используя I1.super.getGreeting();. Он может получить доступ либо к обоим, либо к никому. Таким образом, следующая допустимая реализация C1

public class C1 implements I1, I2{
    public static void main(String[] args)
    {
        System.out.println(new C1().getGreeting());
    }

    @Override //class is obliged to override this method
    public String getGreeting() {
        //can use both default methods
        return I1.super.getGreeting()+I2.super.getGreeting();
    }

    public String useOne() {
        //can use the default method within annother method
        return "One "+I1.super.getGreeting();
    }

    public String useTheOther() {
        //can use the default method within annother method
        return "Two "+I2.super.getGreeting();
    }


}
5
ответ дан Community 27 August 2018 в 03:13
поделиться

Я считаю, что правило состоит в том, что класс, реализующий повторяющиеся методы по умолчанию, должен «переопределить реализацию». Следующие компилируются и выполняются отлично ...

public class DupeDefaultInterfaceMethods {

interface FirstAbility {
    public default boolean doSomething() {
        return true;
    }
}

interface SecondAbility {
    public default boolean doSomething() {
        return true;
    }
}

class Dupe implements FirstAbility, SecondAbility {
    @Override
    public boolean doSomething() {
        return false;
    }
}

public static void main(String[] args) {
    DupeDefaultInterfaceMethods ddif = new DupeDefaultInterfaceMethods();
    Dupe dupe = ddif.new Dupe();
    System.out.println(dupe.doSomething());

    }
}

> false
0
ответ дан Eddie B 27 August 2018 в 03:13
поделиться

Это не относится к вопросу. Но я все же думаю, что это добавляет некоторую ценность контексту. В дополнение к ответу @ toni77 я хотел бы добавить, что метод по умолчанию может быть вызван из класса реализации, как показано ниже. В приведенном ниже коде метод по умолчанию getGreeting() из interface I1 вызывается из переопределенного метода:

public interface I1 {
     default String getGreeting() {
        return "Good Morning!";
     }
}

public class C1 implements I1, I2 {       
    @override
    public String getGreeting() {
        return I1.super.getGreeting();
    }
}
18
ответ дан James Dunn 27 August 2018 в 03:13
поделиться

Существует случай, когда это действительно работает в соответствии с правилами разрешения. Если один из интерфейсов расширяет один из других.

Используя пример сверху:

public interface I2 extends I1 {
    default String getGreeting() {
        return "Good Afternoon!";
    }
}

Результат будет:

Добрый день!

Однако я считаю, что это будет большой проблемой. Вся причина для интерфейсов по умолчанию заключается в том, чтобы позволить разработчикам библиотеки развивать apis без нарушения исполнителей.

Понятно, что они не позволяют методам компилироваться без структуры наследования через расширение, потому что разработчик библиотеки может потенциально злоупотреблять поведением.

Тем не менее, это может быть самопровозглашено. Если класс реализует два интерфейса, которые не связаны с иерархическим представлением, но оба определяют одну и ту же подпись по умолчанию, тогда класс, который расширяет оба интерфейса, не будет компилироваться. (как показано выше)

Можно предположить, что два разных разработчиков библиотеки могли бы принять решение добавлять методы по умолчанию в разное время, используя общие подписи; на самом деле, вероятно, это произойдет в библиотеках, которые реализуют подобные концепции, такие как математические библиотеки. Если вам повезет, что вы используете оба интерфейса в одном классе, вы будете нарушены при обновлении.

1
ответ дан TechTrip 27 August 2018 в 03:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: