Новая функция, входящая в JDK 8, позволяет добавлять к существующему интерфейсу, сохраняя двоичную совместимость.
Синтаксис похож на
public interface SomeInterface() {
void existingInterface();
void newInterface() default SomeClass.defaultImplementation;
}
Таким образом, для всех существующих реализаций, SomeInterface
когда они обновляются до этой новой версии, они не все внезапно обнаруживают ошибки компиляции newInterface()
.
Что происходит, когда вы реализуете два интерфейса, в которые добавлен новый метод по умолчанию, который вы не реализовали? Разрешите пояснить на примере.
public interface Attendance {
boolean present() default DefaultAttendance.present;
}
public interface Timeline {
boolean present() default DefaultTimeline.present;
}
public class TimeTravelingStudent implements Attendance, Timeline {
}
// which code gets called?
new TimeTravelingStudent().present();
Было ли это определено как часть JDK 8?
Я обнаружил, что боги Java говорят о чем-то похожем здесь http://cs.oswego.edu/pipermail/lambda-lib/2011-Feb February/000068.html , но это часть частного списка рассылки, и я не могу спросить их напрямую.
См. Дополнительные сведения о том, как будут использоваться значения по умолчанию в JDK 8 и расширить интерфейс Collection для поддержки лямбда-выражений: https://oracleus.wingateweb.com/published/oracleus2011/sessions/25066/25066_Cho223662.pdf
Ответы:
Ответ на дублирующую операцию:
Мой ответ на ваш вопрос: да, это форма множественного наследования, потому что вы можете унаследовать поведение от разных родителей. Чего не хватает, так это наследования состояний, т. Е. Атрибутов.
источник
Я знаю, что это старый пост, но поскольку я работаю с этим ...
У вас будет ошибка компилятора, сообщающая вам, что:
источник
Возможны два сценария:
1) Во-первых, это было упомянуто там, где нет конкретного интерфейса
public interface A { default void doStuff(){ /* implementation */ } } public interface B { default void doStuff() { /* implementation */ } } public class C implements A, B { // option 1: own implementation // OR // option 2: use new syntax to call specific interface or face compilation error void doStuff(){ B.super.doStuff(); } }
2) Во-вторых, когда ЕСТЬ более конкретный интерфейс:
public interface A { default void doStuff() { /* implementation */ } } public interface B extends A { default void doStuff() { /* implementation */ } } public class C implements A, B { // will use method from B, as it is "closer" to C }
источник
Да, но вы можете добавить в свой интерфейс методы получения и установки, которые затем должны реализовать классы реализации. Тем не менее, реализующие классы не наследуют атрибуты. Итак, AFAICS, это больше похоже на решение в стиле признака, а не на решение в стиле множественного наследования.
источник
Вкратце: это ошибка времени компиляции, она должна вручную переопределить метод в реализации.
Назначение метода по умолчанию
Основная цель внедрения метода по умолчанию в Java 8 - сделать интерфейс расширяемым без нарушения существующих реализаций (существует так много сторонних библиотек Java).
И,
multiple inheritance
как и в C ++, на самом деле следует избегать, это определенно не цель метода по умолчанию в Java.Как переопределить
2 варианта:
super
формат:<interface_name>.super.<method_name>();
Подсказки:
public
ключевое слово при его переопределении.источник
Если кто-то все еще ищет ответ, если класс реализует два интерфейса с одним и тем же методом по умолчанию, тогда классу необходимо разрешить неоднозначность, предоставив собственную реализацию. Посмотрите это руководство, чтобы узнать больше о том, как работает наследование в методах по умолчанию.
источник
«Как мы будем различать методы» - это вопрос, который был задан Stackoverflow и относился к этому вопросу: конкретные методы в интерфейсах Java1.8.
Ниже приводится пример, который должен ответить на этот вопрос:
interface A{ default public void m(){ System.out.println("Interface A: m()"); } } interface B{ default public void m(){ System.out.println("Interface B: m()"); } } class C implements A,B { public void m(){ System.out.println("Concrete C: m()"); } public static void main(String[] args) { C aC = new C(); aC.m(); new A(){}.m(); new B(){}.m(); } }
Класс C выше должен реализовывать свой собственный конкретный метод интерфейсов A и B. А именно:
public void m(){ System.out.println("Interface C: m()"); }
Для вызова реализации бетона в виде метода из определенного интерфейса , вы можете создать экземпляр в интерфейсе и явно вызывать на метод бетонного этого интерфейса
Например, следующий код вызывает конкретную реализацию метода m () из интерфейса A :
new A(){}.m();
Результатом выше будет:
Интерфейс A: m ()
источник
Насколько я понимаю, это не множественное наследование, потому что они не имеют состояния. Таким образом, методы виртуального расширения не поддерживают полную функциональность объекта или класса.
источник