Являются ли значения по умолчанию в 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 и расширении интерфейса Collection для поддержки lambdas см. в этом разделе. https://oracleus.wingateweb.com/published/oracleus2011/sessions/25066/25066_Cho223662.pdf

Ответ 1

Видео-сеанс для просмотра находится здесь http://medianetwork.oracle.com/video/player/1113272518001 Это дизайнер, говорящий о функции, называемой Virtual Extensions. Он также говорит о том, как это не нарушает совместимость.

Ответ 2

Ответ на дублируемую операцию:

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

Мой ответ на ваш вопрос: Да, это форма множественного наследования, потому что вы можете наследовать поведение от разных родителей. Что не хватает для наследования состояний, т.е. е., атрибуты.

Ответ 3

Я знаю, что это старый пост, но поскольку я работаю с этим материалом...

У вас будет ошибка от компилятора, сообщив вам, что:

 класс TimeTravelingStudent наследует несвязанные значения по умолчанию для present() из типов Attendance and Timeline ссылка на настоящее является неоднозначной, оба метода присутствуют() в Timeline и метод present() в матче Attendance.

Ответ 4

Мой ответ на ваш вопрос: Да, это форма множественного наследования, потому что вы можете наследовать поведение от разных родителей. Что не хватает для наследования состояний, т.е. е., атрибуты.

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

Ответ 5

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

Ответ 6

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


Назначение метода по умолчанию

Основная цель внедрения метода по умолчанию в Java 8 состоит в том, чтобы сделать интерфейс расширяемым, не нарушая существующие реализации (существует так много сторонних библиотек Java).

И multiple inheritance, как в С++, на самом деле предполагается избегать, что определенно не является целью метода по умолчанию в Java.


Как переопределить

2 варианта:

  • Переопределите метод с его собственной логикой.
  • Переопределите метод, вызовите один из методов интерфейса через super, format: <interface_name>.super.<method_name>();

Советов:

  • метод из интерфейса по умолчанию является общедоступным, поэтому не забудьте добавить ключевое слово public, если оно переопределено.

Ответ 7

Существуют сценарии два:

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) Во-вторых, когда IS - более конкретный интерфейс:

   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
    }

Ответ 8

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