По умолчанию в JDK 8 в форме множественного наследования в Java?
новая функция, входящая в 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-February/000068.html, но это часть частного списка рассылки, и я не могу спросить их напрямую.
см. это для получения дополнительной информации о том, как значения по умолчанию будут использоваться в JDK 8 и расширения интерфейса сбора для поддержки лямбды: https://oracleus.wingateweb.com/published/oracleus2011/sessions/25066/25066_Cho223662.pdf
8 ответов:
видеосессия для просмотра здесь http://medianetwork.oracle.com/video/player/1113272518001 это дизайнер говорит о функции под названием Виртуальные расширения. Он также говорит о том, как это не нарушает обратную совместимость.
ответ на дублирующую операцию:
для решения проблемы множественного наследования класс, реализующий два интерфейса, обеспечивающих реализацию по умолчанию для одного и того же имени метода и подписи, должен обеспечить реализацию метода. [Полный Текст Статьи]
мой ответ на ваш вопрос: Да, это форма множественного наследования, потому что вы можете наследовать поведение от разных родителей. Чего не хватает, так это наследовать состояния, то есть, атрибуты.
Я знаю, это старый пост, но так как я работаю с этим материалом...
вы будете иметь ошибку от компилятора, говоря вам, что:
class класс TimeTravelingStudent наследует несвязанные значения по умолчанию для present() от типов посещаемости и временной шкалы ссылка на present неоднозначна, как метод present() на временной шкале, так и метод present() в матче посещаемости.
мой ответ на ваш вопрос: Да, это форма множественного наследования, потому что вы можете наследовать поведение от разных родителей. Чего не хватает, так это наследовать состояния, т. е. атрибуты.
да, но вы можете добавить геттеры и сеттеры в свой интерфейс, что реализация классов должны реализовать. Тем не менее, реализующие классы не наследуют атрибуты. Итак, AFAICS, это больше похоже на решение в стиле признака, а не на множественное наследование стилевое решение.
короче говоря: это ошибка времени компиляции, необходимо над методом вручную в реализации.
назначение метода по умолчанию
основная цель внедрения метода по умолчанию в Java 8 - сделать интерфейс расширяемым, не нарушая существующие реализации (есть так много сторонних библиотек Java).
и
multiple inheritance
как и в C++, на самом деле предполагается избегать, это определенно не цель метода по умолчанию в Ява.
как переопределить
2 варианта:
- переопределить метод, со своей логикой.
- переопределите метод, вызовите один из методов интерфейса через
super
формат:<interface_name>.super.<method_name>();
советы:
- метод из интерфейса по умолчанию является общедоступным, поэтому не забудьте добавить
public
ключевое слово при переопределении его.
Если кто-то все еще ищет ответ, в случае, если класс реализует два интерфейса с тем же методом по умолчанию, то класс должен решить неоднозначность, предоставив собственную реализацию. Посмотри на этой учебник для получения более подробной информации о том, как наследование в стандартные методы работы.
здесь два сценарии:
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 }