Pergunta

Wikipedia no problema do diamante:

"... o problema do diamante é uma ambiguidade que surge quando duas classes B e C herdam de A e Classe D herda de B e C. Se um método em D chama um método definido em A (e não substitui o método ), e B e C substituíram esse método de maneira diferente, então de qual classe herda: B ou C? "

Então o diamante se parece com o seguinte:

  A
 / \
B   C
 \ /
  D

Minha pergunta é: o que acontece se não existe essa classe A, mas novamente B e C declaram o mesmo método, digamos Foo (). Não é o mesmo problema? Por que isso é chamado de problema de diamante?

Exemplo:

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

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

class D extends B, C {
}

new D().foo();
Foi útil?

Solução

Não é o mesmo problema.

No problema original, o método de substituição pode ser chamado de A. Em seu problema, esse não pode ser o caso, porque ele não existe.

No problema do diamante, o confronto acontece se a classe A chamar o método foo. Normalmente, isso não é problema. Mas na classe D você nunca pode saber qual caso de Foo precisa ser chamado:

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

No seu problema, não há ancestral comum que possa chamar o método. Na classe D, existem dois sabores de Foo que você pode escolher, mas pelo menos você sabe que existem dois. E você pode fazer uma escolha entre os dois.

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

Mas, como sempre, você não precisa de herança múltipla. Você pode usar AggeGration e Interfaces para resolver todos esses problemas.

Outras dicas

No problema do diamante, a classe D herda implicitamente o método virtual da Classe A. para chamá -lo, a classe D ligaria:

A::foo()

Se as duas classes B e C substituírem esse método, o problema surgirá realmente chamado.

No seu segundo exemplo, no entanto, esse não é o caso, pois a classe D precisaria declarar explicitamente o que estava sendo chamado:

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

Portanto, os problemas não são realmente os mesmos. No problema do diamante, você não está referenciando as classes derivadas, mas a classe base, daí a ambiguidade.

É assim que eu entendo, de qualquer maneira.

Observe que estou vindo de um fundo C ++.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top