Java, как я могу преодолеть множественное наследование и алмазную проблему

Я пытаюсь понять, как я могу преодолеть «алмазную проблему» в JAVA, скажем, у меня есть эти 3 интерфейса:

interface Alpha{
    public default int methodA() {
        int result=0;
        System.out.println("Print from Alpha methodA");
        return result+4;
    }
}

//**********************************

interface Betta extends Alpha {
    public default int methodA() {
        int result=0;
        System.out.println("Print from Betta methodA");
        return result+8;
    }
}
//*******************************

interface Gamma extends Alpha {
    public default int methodA() {
        int result=0;
        System.out.println("Print from Gamma methodA");
        return result+16;
    }
}

И этот класс:

public class Delta implements Betta,Gamma {
    public static void main(String args[]) {
    // TODO Auto-generated method stub

    Delta cObj=new Delta();
    cObj.methodA();
}

как я могу получить класс Delta, дающий мне вывод интерфейса Alpha? Есть ли другой способ, кроме как изменить его на «Дельта реализует альфа-канал»?


person Liana    schedule 03.01.2017    source источник
comment
Вы не можете получить доступ к методу, который был переопределен. Если вам нужен доступ к нему, вам нужно добавить метод, который вы можете вызвать, который может классифицировать этот метод, например. на Бетту или Гамму.   -  person Peter Lawrey    schedule 03.01.2017
comment
Если все в порядке, вы можете определить метод static в интерфейсе Alpha и вызвать его из класса Delta.   -  person SachinSarawgi    schedule 03.01.2017
comment
Вы пробовали это компилировать?   -  person Klitos Kyriacou    schedule 03.01.2017
comment
Спасибо, Питер Лоури, я попробую   -  person Liana    schedule 03.01.2017
comment
SachinSarawgi, но если я это сделаю, тогда Бетта и Гамма бесполезны, я прав?   -  person Liana    schedule 03.01.2017
comment
@ Лиана, ты прав, я просто попытался дать решение. В вашем случае это может быть бесполезно.   -  person SachinSarawgi    schedule 03.01.2017
comment
да, я получаю эту ошибку Дублированные методы по умолчанию с именем methodA с параметрами () и () наследуются от типов Gamma и Betta @Klitos Kyriacou   -  person Liana    schedule 03.01.2017


Ответы (2)


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

Вы можете сделать это так:

public class Delta implements Betta, Gamma {
    public static void main(String[] args) {
        Delta cObj = new Delta();
        cObj.methodA();
    }

    @Override
    public int methodA() {
        return Betta.super.callSuperMethodA();
    }
}

public interface Betta extends Alpha {

    public default int methodA() {
        int result = 0;
        System.out.println("Print from Betta methodA");
        return result + 8;
    }

    //Call this from Delta default method
    public default int callSuperMethodA() {
        return Alpha.super.methodA();
    }

}
person Rohit Gulati    schedule 03.01.2017
comment
Я тоже думал об этом, но я получаю метод Print from Betta, и когда я пытаюсь использовать Alpha.methodA(); внутри интерфейса Betta я получаю как Print from Betta methodA, так и Print from Alpha methodA @Rohit Gulati - person Liana; 03.01.2017
comment
извините, мой плохой, я неправильно истолковал ваш вопрос, мы не можем получить к нему доступ. Перейдите по этой ссылке. Нам придется сделать его статическим или расширить Альфу. - person Rohit Gulati; 03.01.2017
comment
Альтернатива: вы можете добавить еще один метод по умолчанию в Betta, где вы вызываете метод Alpha Default. Обновил сообщение выше. @Лиана - person Rohit Gulati; 03.01.2017
comment
Большое спасибо за помощь! Я получаю это сейчас - person Liana; 03.01.2017

Вы можете либо превратить метод Alpha в статический

public interface Alpha {
public static int methodA(){
    int result = 0;
    System.out.println("Print from Alpha methodA");
    return result+4;
}}

или вы можете создать метод, ссылающийся на метод Alpha в Betta или Gamma.

Третьим необязательным решением этой проблемы может быть удаление реализации по умолчанию для Gamma и Betta, что означает полное опустошение их обеих.

person Damir Bar    schedule 05.01.2017