Problema de diamante
-
20-09-2019 - |
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();
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 ++.