Ромбовидная проблема

Википедия на ромбовидной проблеме:

"... ромбовидной проблемой является неоднозначность, которая возникает, когда два класса B и C наследовались A, и класс D наследовался и B и C. Если метод в D называет метод определенным в (и не переопределяет метод), и B и C переопределили тот метод по-другому, то, от которого класс, он наследовался: B, или C?"

Таким образом, ромб похож на это:

  A
 / \
B   C
 \ /
  D

Мой вопрос, что происходит, если нет такого класса A, но снова B, и C объявляют тот же метод, говорят нечто (). Разве это не та же проблема? Почему это тогда называют ромбовидной проблемой?

Пример:

class B {
    public void foo() {...}
}

class C {
    public void foo() {...}
}

class D extends B, C {
}

new D().foo();
27
задан Valentin Rocher 14 January 2010 в 14:58
поделиться

2 ответа

Это не та же проблема.

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

В проблеме алмазов столкновение случается, если класс a вызывает метод foo. Обычно это не проблема. Но в классе D вы никогда не можете знать, какой экземпляр FOO должен быть вызван:

         +--------+
         |   A    |
         | Foo    |
         | Bar    |
         +--------+
            /  \
           /    \
          /      \
+--------+        +--------+
|   B    |        |   C    |
| Foo    |        | Foo    |
+--------+        +--------+
          \      /
           \    /
            \  /
         +--------+
         |   D    |
         |        |
         +--------+

в вашей проблеме, нет общего предка, который может вызвать метод. На классе D есть два аромата FOO, которые вы можете выбрать, но, по крайней мере, вы знаете, что есть два. И вы можете сделать выбор между двумя.

+--------+        +--------+
|   B    |        |   C    |
| Foo    |        | Foo    |
+--------+        +--------+
          \      /
           \    /
            \  /
         +--------+
         |   D    |
         |        |
         +--------+

Но, как всегда, вам не нужен многократный наследство. Вы можете использовать Aggegration и интерфейсы для решения всех этих проблем.

12
ответ дан 28 November 2019 в 05:50
поделиться

В алмазной проблеме класс d неявно наследует виртуальный метод из класса A. Чтобы вызвать его, Class D позвонит:

A::foo()

, если оба класса B и C переопределяют этот метод, то проблема на самом деле вызывается Отказ

Во втором примере это не так, как класс D должен быть явно Государство, которое называется:

B::foo()
C::foo()

Так что проблемы на самом деле не одинаковы. В алмазной проблеме вы не ссылаетесь на полученные классы, но их базовый класс, следовательно, неоднозначность.

Вот как я это понимаю, все равно.

Обратите внимание, что я иду с фона C ++.

10
ответ дан 28 November 2019 в 05:50
поделиться
Другие вопросы по тегам:

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