Pregunta

Wikipedia sobre el problema de diamante:

" ... el problema diamante es una ambigüedad que surge cuando dos clases B y C heredan de A, y la clase D hereda de ambos B y C. Si un método en el D llama a un método definido en A (y no reemplazar el método), y B y C han anulado ese método diferente, a continuación, a partir del cual la clase no se heredan:? B, o C "

Así que el diamante es el siguiente:

  A
 / \
B   C
 \ /
  D

Mi pregunta es, ¿qué ocurre si no hay tal clase A, pero de nuevo B y C declarar el mismo método, por ejemplo foo (). No es éste el mismo problema? ¿Por qué es entonces llamado problema de diamantes?

Ejemplo:

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

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

class D extends B, C {
}

new D().foo();
¿Fue útil?

Solución

No es el mismo problema.

En el problema original, el método puede ser llamado overriden de A. En su problema esto no puede ser el caso, ya que no existe.

En el problema de diamantes, el choque sucede si la clase A llama al método Foo. Normalmente esto no es problema. Pero en la clase D nunca se puede saber qué instancia de Foo necesita ser llamado:

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

En su problema, no existe un ancestro común que se puede llamar al método. En la clase D hay dos sabores de Foo usted puede elegir, pero al menos se sabe que hay dos. Y usted puede hacer una elección entre los dos.

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

Pero, como siempre, no es necesario herencia múltiple. Puede utilizar aggegration e interfaces para resolver todos estos problemas.

Otros consejos

En el problema de diamante, clase D hereda implícitamente el método virtual de la clase A. Para llamarlo, clase D llamaría:

A::foo()

Si ambas clases B y C reemplazar este método, entonces el problema viene de que en realidad es llamada.

En el segundo ejemplo, sin embargo, este no es el caso ya que la clase D tendría que explícitamente estado que estaba siendo llamado:

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

Así que los problemas no son en realidad la misma. En el problema de diamantes que no se hace referencia a las clases derivadas, pero su clase base, de ahí la ambigüedad.

Así es como yo lo entiendo, de todos modos.

Tenga en cuenta que vengo de un fondo de C ++.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top