Джава:как вы называете эту неоднозначность множественного наследования?

StackOverflow https://stackoverflow.com/questions/2261954

Вопрос

Вот пример использования множественного наследования интерфейсов в Java, и здесь возникла проблема.

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

Например, в C++ неоднозначность, которая возникает, когда вы используете множественное наследование реализации и не можете определить, какой переопределенный метод использовать, называется «проблемой ромба»:

http://en.wikipedia.org/wiki/Diamond_problem

Еще раз, я знаю, что здесь не та же проблема:не в этом дело.Дело в том, что в предыдущем случае было придумано имя.

И мне хотелось бы знать, существует ли название проблемы, которую я собираюсь описать.

Вот пример другого типа множественного наследования, когда один интерфейс наследуется от двух других интерфейсов, имеющих несовместимый тип возвращаемого метода:

interface A {
  void a();
  Integer c();
}

interface B {
  void b();
  Long c();
}

interface MI extends A, B {...}

(обратите внимание на множественное наследование интерфейсов при использовании ключевого слова «extends»)

Вы не можете этого сделать, потому что:

типы А и Б несовместимы;Оба определяют c (), но с не связанным с собой типом возврата

Было ли придумано название для описания этой ситуации?

Это было полезно?

Решение

Я не уверен, что для него существует конкретное название, или, по крайней мере, оно, похоже, не очень часто используется.Это «всего лишь» проблема неявного отображения методов интерфейса на методы класса;если бы у вас были перегрузки, которые различались бы только типами возвращаемых значений, проблем тоже не было бы.Таким образом, все сводится к проблеме сопоставления сигнатуры/перегрузки/неявного метода.

В онлайн-книге «Мышление на Java» для него тоже нет названия.http://www.linuxtopia.org/online_books/programming_books/thinking_in_java/TIJ310_001.htm

К слову, C# допускает явную реализацию интерфейса, что решает эту проблему.

Другие советы

JLS §6.4.4, Члены типа интерфейса вызывает такие повторяющиеся члены суперинтерфейса двусмысленный, и требует ошибки времени компиляции.Я надеялся на что-то красочное, например Эффект Божоле, Гейзенбаг, и другие.Может быть двое в толпе?

Я также не знаю какого-либо конкретного названия этой проблемы.Всякий раз, когда оно возникало, оно описывалось в предложении, содержащем слова несовместимость типа возвращаемого значения в какой-то момент.Вы также можете назвать это Несовместимость карты/набора поскольку это один из наиболее ярких и раздражающих примеров в библиотеках классов Java.Это делает невозможным реализацию одного и того же класса Map, а также Set или Collection только потому, что Map определяет удалить (Объект) метод с типом возвращаемого значения, отличным от Collection.

public interface Collection<E> extends Iterable<E> {
    boolean remove(Object o);
}
public interface Set<E> extends Collection<E> {
}
public interface Map<K,V> {
    V remove(Object key);
}

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

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

Я не помню, видел ли я когда-нибудь какое-нибудь название для этого.В Спецификация языка Java этому тоже нет названия.

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

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

Схема, реализованная в .NET, там прекрасно работает.К сожалению, в Java невозможно сделать что-то подобное.Я не знаю, будет ли Java издавать сигналы, если интерфейс наследует другие интерфейсы с конфликтующими членами, но независимо от того, издаст ли он в этот момент сигнал или нет, не будет способа создать класс, который мог бы его реализовать.

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

Я упустил суть или вы говорите о переменной «c»?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top