Problema do diamante: Diferenzas entre revisións

Contido eliminado Contido engadido
EmausBot (conversa | contribucións)
m Bot: Retiro 4 ligazóns interlingüísticas, proporcionadas agora polo Wikidata en d:Q18224733
Unhanova (conversa | contribucións)
Sen resumo de edición
Liña 1:
[[Ficheiro:Diamond inheritance.svg|miniatura|dereita|Un diagrama de herdanza en diamante.]]
 
En [[Linguaxe de programación|linguaxes de programación]] [[programación orientada a obxectos|orientada a obxectos]], o '''problema do diamante''' é unha ambigüidade que xurdexorde cando dousdúas [[clase (Informática)|clases]] B e C [[herdanza (programación orientada a obxectos)|herdan]] de A, e a clase D herda de B e C. Se un [[métodos (programación orientada a obxectos)|método]] en D chama a un método definido en A, ¿por qué cal clase o herda, B ou C?
 
Chámase o problema do 'diamante' pola forma do diagrama de herdanza de clase nesta situación. A clase A está enriba, B e C están separadas debaixo dela, e D únese ás dúas na parte inferior conseguindo a forma dun diamante.
Liña 9:
 
* [[C++]] por defecto segue cada ruta de herdanza por separado, polo que un obxecto D realmente contendería dous obxectos A separados, e o uso dos membros de A debe ser adecuadamente definido. Se a herdanza de A a B e a herdanza de A a C están marcadas como "virtuais" ("class B : virtual A"), C++ preocúpase por crear só un obxecto A, e o uso dos membros de A funciona correctamente. Se [[herdanza virtual]] e herdanza non virtual son mesturadas, hai un só A virtual e un só A non virtual para cada ruta de herdanza non virtual a A.
* [[Common Lisp]] intenta ofrecer tanto o comportamento por defecto como a capacidade de redefinilo. Por defecto, escóllese o método coas clases argumento máis específicas <!-- traducido do artigo inglés. que significa? -->; é dicir, na orde na que as clases pai son nomeadas na definición da subclase. Sen embargoPorén, o programador pode redefinir isto, dando unha orde de resolución de método específico ou establecendo unha regra para a combinación de métodos.
* [[Eiffel]] manexa esta situación seleccionando e renomeando directivas, onde os métodos dos ascendentes a empregar nun descendente son explicitamente especificados. Isto permite que os métodos da clase base sexan compartidos entre seus descendentes o incluso dar a cada unoun dedeles eles unaunha copia separada de lada clase base.
* [[Perl]] ye [[Ío (lúalinguaxe de programación)|Ío]] manexan isto mediante a especificación das clases de herdanza nunha lista ordenada. Na ambigüidade mostrada arriba, a clase B e os seus ascendentes serían comprobados antes da clase C e os seus ascendentes, polo que o método A sería herdado a través de B.
* [[Python]] ten que tratar con isto dende a introdución de clases de novo estilo, das que todas teñen un ascendente común, <code>object</code>. Python crea unaunha lista de clases que se buscan de esquerda a dereita e de abaixo cara a arriba (D, B, A, C, A) e logo elimina tódalas aparicións dunha clase repetida menos a última. Polo que, a orde de resolución do método é: D, B, C, A.
 
== Outros exemplos ==
Linguaxes que só permiten herdanza simple como (como [[Objective-C]], [[PHP]], [[C#]], e [[Java (linguaxe de programación)|Java]]) permiten a [[herdanza múltiple]] de interfaces (chamadas protocolos en Objective-C). As interfaces son esencialmente clases base abstractas con tódolos métodos abstractos e sen membros de datos. O problema é por tanto evitado xa que sempre hai só unha implementaciónposta en funcionamento para un método ou propiedade específico e non xorde ningunha ambigüidade.
 
O problema do diamante non está limitado á herdanza. Tamén xorde cando arquivos de cabeceira A, B, C e D inclúen ("#include") os uns ós outros nun diamante como arriba e cabeceiras precompiladas separadas son creadas dende B e C. Se estas dúas cabeceiras precompiladas son combinadas, as declaracións en A son duplicadas e a convención "#ifndef" non é efectiva. Tamén atópase ó compoñer pilas de [[middleware]]; por exemplo, se A é unha base de datos e B e C son cachescachés, D pode pedir tanto a B como a C a confirmación dunha transacción, dando lugar a chamadas de confirmación a A duplicadas.
 
== Véxase tamén ==