2009-06-24 27 views
8

He creado dos granosAlternativa de herencia múltiple en Java

class BackPageBean{ 
    String backPage = null; 
    : 
    : 
    : 
} 


class InformationMessageBean{ 
    String informationMessage = null; 
    : 
    : 
    : 
} 

Ahora, si una clase es backpage conscientes entonces se extenderá backPageBean, o si necesita mostrar algún tipo de mensaje a continuación, se extiende InformationMessageBean.

class BackPageAware extends backPageBean{ 
} 

class InfoMessAware extends InformationMessageBean{ 
} 



    someFunction() { 
     if (theObject instanceOf backPageBean) { 
       prepareTheBackPage (theObject.getBackPage()); 
     } 

     if (theObject instanceOf InformationMessageBean) { 
       showtheInformation (theObject.getMessage()); 
     } 

    } 

Ahora el problema es que si quiero tener un grano que es tanto BackPageAware, así como InformationAware entonces, como no tenemos la herencia múltiple, lo que debería ser el enfoque?

+3

Es Java. No JAVA. –

+1

nunca sabía, thnx: D –

Respuesta

9

Solo para aclarar mi comentario.

Al igual que Darth Eru dice que cree las dos interfaces y las dos implementaciones predeterminadas . Cuando tiene un bean que necesita los dos comportamientos , esa clase implementa las dos interfaces pero también crea las variables de las implementaciones predeterminadas. De esta manera todavía no necesita duplicar ningún código.

interface InfoMessAware { 

     String getMessage(); 
    } 

    interface BackPageAware { 

     String getBackPage(); 
    } 

class DefaultInfoMessAware { 
     String getMessage() { 
      return "message"; 
     } 
} 

class DefaultBackPageAware { 
     String getBackPage() { 
      return "backPage"; 
     } 
} 

    class MyBean implements InfoMessAware, BackPageAware { 
     private InfoMessAware messAware = new DefaultInfoMessAware(); 
     private BackPageAware backPageAware = new DefaultBackPageAware(); 

     String getMessage() { 
      return messAware.getMessage(); 
     } 

     String getBackPage() { 
      return backPageAware.getBackPage(); 
     } 
    } 
+0

¿Por qué 'DefaultInfoMessAware' y' DefaultBackPageAware' no implementan respectivamente las interfaces 'InfoMessAware' y' BackPageAware'? –

11

utilizar interfaces:

interface InfoMessAware { 

    String getMessage(); 
} 

interface BackPageAware { 

    String getBackPage(); 
} 

class MyBean implements InfoMessAware, BackPageAware { 

    String getMessage() { 
     return "message"; 
    } 

    String getBackPage() { 
     return "backPage"; 
    } 
} 

luego vuelva a colocar instanceof con llamadas a métodos estándar.

+1

Eso significa ciertamente voy a tener que tener la (misma) definición de getbackpage y getMessage en toda clase que se va a poner en práctica estos interfaz. cadena getMessage() { retorno this.message; } // tendremos un colocador también cadena getbackPage() { retorno this.backPage; } // tendremos un colocador también –

+0

lamentablemente Java tiene herencia múltiple sólo para las interfaces – dfa

0

Declaran BackPageAware y InformationAware como interfaces, crean clases abstractas que implementan esas interfaces para proporcionar la funcionalidad predeterminada. Cualquier clase que necesita ser solo una de las dos interfaces puede heredar la clase abstracta correspondiente. Una clase que necesita ser ambas puede heredar una de las clases abstractas e implementar la otra interfaz, o implementar ambas interfaces, lo que sea. Si no hay una funcionalidad predeterminada, entonces ni siquiera necesita las clases abstractas.

+1

Si una clase necesita ambos comportamientos Me implementan las interfaces y delegar en el implementaciones por defecto. Has-A rocks :) – willcodejavaforfood

+0

¿podrías elaborar willcode? –

+0

Al igual que Darth Eru dice que crea las dos interfaces y las dos implementaciones predeterminadas. Cuando tiene un bean que necesita ambos comportamientos, tiene que implementar las dos interfaces pero también crea variables de las implementaciones predeterminadas. De esta forma, aún no necesita duplicar ningún código. – willcodejavaforfood

0

No puede extender múltiples clases pero puede implementar múltiples interfaces. Recuerde que cuando aplica una interfaz a una clase, el objeto de la clase tiene una relación IS-A con la interfaz.

8

El problema que está describiendo exige el uso de la composición, no de la herencia. La clase que es BackPageAware significa que sabe acerca de esa clase/funcionalidad. Herencia significa que es IS a BackPage. Usted ha descrito una relación HAS A.

Como se ha dicho muchas veces, utilice interfaces para definir los contratos para recuperar la información que el objeto TIENE.

1

Sus dos clases originales deben ser interfaces, cada uno con un método en ellos, que recupera la información de que las implementaciones deben volver.

public interface BackPageBean { 
    public String getBackPage(); 
} 


public interface InformationMessageBean { 
    public String getInformationMessage(); 
} 

Si quieres una clase para implementar tanto BackPageBean y InformationMessageBean simplemente hacer esto:

public MyBean implements BackPageBean, InformationMessageBean { 

    public String getBackPage() { 
    return null; 
    } 

    public String getInformationMessage() { 
    return null; 
    } 
} 

En términos generales, se debe evitar extender las clases no abstractos siempre que pueda, que conduce a todas las clases de problemas En su lugar, intente utilizar la composición en lugar de la herencia cuando se trate de clases concretas, y de lo contrario, trate de apegarse a las interfaces y a la clase abstracta ocasional.

1

Como se ha comentado en otras respuestas herencia múltiple se puede simular por medio de interfaces y composición, a costa de tener que escribir una gran cantidad de código repetitivo. Sin embargo, hay una serie de proyectos que pueden automatizar esto en tiempo de compilación (a través de un preprocesador) o en tiempo de ejecución, por ejemplo, jmixin.

+0

1 para señalar la necesidad de escribir una gran cantidad de [código repetitivo] (https://en.wikipedia.org/wiki/Boilerplate_code), que es una omisión sorprendentemente frecuente en "prefieren composición sobre la herencia" consejos, por lo que tales técnica parece una alternativa sin pérdidas a la herencia, mientras que definitivamente no lo es. – SantiBailors

0

Puede tener BackPageAware y InformationAware como interfaces en lugar de clases. Esto le permite buscar los mensajes de ambas interfaces en el caso de que el 'bean' al que se refiere sea de BackPageAware y InformationAware.

public class Name implements BackPageAware, InformationAware {}