По умолчанию в 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 71

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
    }

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