Реализация метода по умолчанию интерфейса Java [duplicate]

У меня была та же проблема, когда я отправил данные с помощью jQuery AJAX:

$.ajax({
   url:...
   success:function(data){
      //server response's data is JSON
      //I use jQuery's parseJSON method 
      $.parseJSON(data);//it's ERROR
   }
});

Если ответом является JSON, и вы используете этот метод, данные, которые вы получаете, являются объектом JavaScript, но если вы используйте dataType:"text", данные - строка JSON. Тогда использование $.parseJSON в порядке.

18
задан Razib 13 October 2016 в 19:06
поделиться

5 ответов

Проблема с алмазом применима только к реализации inheritance (extends во всех версиях Java до Java 8). Это не относится к API inheritance (implements во всех версиях Java до Java 8).

Поскольку методы интерфейса с сигнатурами типа соответствия совместимы, нет алмаз, если вы наследуете одну и ту же подпись метода в два раза: подписи сигнатур метода просто сливаются. (И если сигнатуры типа не совпадают, то у вас также нет проблемы с алмазом.)

В Java 7 и ниже единственный способ наследовать реализацию код был через ключевое слово extends, которое ограничивает не более одного родителя. Поэтому нет наследования множественной реализации и проблемы с алмазом не существует.

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

15
ответ дан Daniel Pryden 18 August 2018 в 22:09
поделиться
  • 1
    Я не думаю, что Java 8 действительно ускользает от проблемы с алмазами. Если B: A, C: A, D: B и D: C и B содержит реализацию по умолчанию для одного из методов A, а C - нет, то эта реализация может использоваться в D, но из того, что я понимаю, это то это будет нарушающее изменение для C, чтобы добавить реализацию этого метода по умолчанию. – supercat 20 April 2015 в 22:35
  • 2
    @supercat: Хорошая точка. В зависимости от вашей точки зрения вы можете сказать, что у Java 8 есть есть проблема с алмазом, но просто делает сложные ошибки времени компиляции, так что поведение легче рассуждать (по сравнению, скажем, , C ++). – Daniel Pryden 20 April 2015 в 22:40
  • 3
    Я не думаю, что они обязательно являются ошибками во время компиляции, так как реализация C по умолчанию могла быть добавлена ​​между временным кодом, использующим D, была скомпилирована и время запуска кода. Я не помню, что делает Java в этом случае, но для сценария выполняется компиляция реализации D, A добавляет член, потребитель D, который использует новый член, скомпилирован, а затем B скомпилирован с реализацией по умолчанию. На этом этапе реализация D и потребитель будут работать. Если C скомпилирован с реализацией по умолчанию, я не вижу хороших действий для JVM. – supercat 20 April 2015 в 22:50
  • 4
    @supercat FYI: JVM будет бросать IncompatibleClassChangeError: Conflicting default methods, если оба варианта B и C имеют реализацию по умолчанию, а D не отменяет. Это как ошибка компиляции, так и ошибка времени выполнения. – Andreas 26 January 2017 в 18:30
  • 5
    @Andreas: Интересно, как часто необходимо добавлять реализации по умолчанию к методу, который объявлен в родительском интерфейсе? Если реализации по умолчанию могут быть добавлены только к интерфейсу, в котором объявлен метод, это позволит избежать проблем с угрозами. С другой стороны, было бы полезно указать несколько перегрузок по умолчанию для метода интерфейса и привязать Java к первой, которая будет удовлетворена классом реализации или, далее, позволить интерфейсу указать, что любой класс, который может удовлетворять перегрузкам для всех его методов, должен быть ... – supercat 26 January 2017 в 18:37

Чтобы добавить к существующим ответам о множественном наследовании Java8 с интерфейсами (так же, как Java все еще избегает проблемы с алмазом):

Существует три правила:

  1. A класс всегда побеждает.
  2. Если класс не имеет: самый конкретный интерфейс выигрывает

  1. Если выше не так, наследующий класс должен явно указать, какую реализацию метода он использует (иначе он не будет компилироваться)

2
ответ дан Andrejs 18 August 2018 в 22:09
поделиться

Java преодолевает эту проблему, даже если интерфейсы могут иметь стандартные реализации методов, потому что реализация по умолчанию либо однозначная (одна в классе A), либо ситуация разрешена некоторыми правило (когда класс B или класс C переопределяет реализацию из класса A, см. ниже).

Когда супертипы класса или интерфейса предоставляют несколько методов по умолчанию с помощью та же подпись:

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

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

См. Также: Как работает новая модель интерфейса Java 8 (включая алмаз, множественное наследование и старшинство)?

3
ответ дан Community 18 August 2018 в 22:09
поделиться
  • 1
    Спасибо за ссылку. Это действительно информативный – Razib 30 April 2015 в 19:16

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

1- Если реализация класса переопределяет метод по умолчанию и предоставляет свои собственные функции для метода по умолчанию то метод класса имеет приоритет над методами интерфейса по умолчанию.

2-Когда класс реализует оба интерфейса, и оба имеют одинаковый метод по умолчанию, также класс не переопределяет этот метод, тогда ошибка будет выбрана .

3. Если интерфейс расширяет другой интерфейс и оба имеют один и тот же метод по умолчанию, метод по умолчанию наследующего интерфейса будет иметь приоритет.

читайте больше об этом здесь .

3
ответ дан infoj 18 August 2018 в 22:09
поделиться

Java не поддерживает множественное наследование, поэтому проблема с алмазом не возникает. Если B & amp; C - интерфейсы, то в интерфейсах нет реализации. Даже если B & amp; C переопределяет метод в интерфейсе A (не может быть классом), методы будут иметь одну и ту же подпись. Нет никакой двусмысленности в отношении того, какую реализацию использовать, потому что нет реализации.

2
ответ дан vinay 18 August 2018 в 22:09
поделиться
  • 1
    Как сказал Дэниел Приден, все становится немного сложнее с Java 8. – vinay 20 April 2015 в 21:10
Другие вопросы по тегам:

Похожие вопросы: