Mejor manera de evitar el código duplicado si dos clases que se extienden de diferentes clases

Estoy trabajando en un proyecto de Android y estoy enfrentando esta situación.

Tengo 2 clases:

class A extends B { openDoor(){ //impl } closeDoor(){ //impl } } class X extends Y{ openDoor(){ //impl } closeDoor(){ //impl } } 

Ahora si observa los dos métodos comunes en las clases openDoor() y closeDoor()

¿Cuál es la mejor manera de evitar los métodos duplicados?

Mi acercamiento

 class ContainingDuplicateMethods{ openDoor(){ //impl } closeDoor(){ //impl } } } 

Crear un objeto de ContainingDuplicateMethods en la clase y llamar a los métodos, que lo llamamos como Strategy Pattern , pero es esta la mejor solución? ¿Por qué porque en grandes proyectos no podemos seguir este enfoque y la gente lo dice no es BUENA PRÁCTICA, en ese caso qué enfoque debo seguir?

Tenga en cuenta que las class A and X ya están extendiendo otras clases y también no quiero usar estática porque – Los miembros estáticos se cargan en la memoria cuando se inicia la ejecución del programa y estarán en la memoria hasta que termine el programa, digamos que mi código se ejecuta continuamente Días o semanas y sigue creando muchos números de objetos usando las referencias estáticas para que haya una posibilidad de que podamos quedarnos sin memoria.

"Favorecer la composición sobre la herencia" es una cosa útil para recordar.

Tener una clase de Door con abrir y cerrar. Incluya una Door como miembro de A y B

Voila, trabajo hecho.

Así que A.getDoor().close() . B.getDoor().open() etc.

Si necesita una interfaz común para A y B (para que pueda utilizar en algún lugar), a continuación, cree

 interface HasDoor { Door getDoor(); } 

Ahora A y B pueden extender cualquier clase que quieras e implementar HasDoor . Cualquier clase que requiera una puerta puede aceptar un HasDoor (o simplemente aceptar directamente el objeto Door ) y llamar abrir, cerrar, etc.

No hay código duplicado, flexibilidad total.

Si necesita que su Door vuelva a llamar a los métodos en A y B , cree la clase Door como abstracto e implemente en A y B como una clase interna anónima. Los métodos abstractos serán llamados de la Door y entonces usted puede hacer cualquier proceso que sea necesario en A y B cuando se llaman esos métodos.

Por ejemplo, la clase A se convierte en:

  class A implements HasDoor { private Door door = new Door() { @override void notifyDoorChanged(boolean closed) { // The door is telling us its been opened or closed } } @override public Door getDoor() { return door; } } 

Donde está la puerta:

  public abstract class Door { boolean closed; abstract notifyDoorChanged(); public void close() { closed = true; notifyDoorChanged(closed); } // etc } 

Tenga en cuenta que esto es similar al patrón de estrategia – pero no es exactamente lo mismo. El patrón de estrategia tiene un objeto maestro y, a continuación, se conectan varias estrategias (es decir, diferentes formas de puerta). Esto tiene una puerta y varios otros objetos que usan el mismo tipo de puerta, aunque usted podría extenderlo para utilizar el patrón de la estrategia y tener múltiples implementaciones de la puerta muy fácilmente.

Esta es la implementación de la respuesta publicada por Tim B. Es un enfoque muy flexible para ir con. Sigue los principios de la reutilización orientada a objetos:

  1. Identificar que varía y separarlos de lo que se mantiene igual.
  2. Programa a una interfaz, no una implementación.
  3. Favorece la composición del objeto sobre la herencia.

    Clase pública Principal {

      public static void main(String[] args) { X x = new X(); A a = new A(); x.getDoor().open(); x.getDoor().close(); a.getDoor().open(); a.getDoor().close(); } } interface HasDoor { Door getDoor(); } interface Door { public void open(); public void close(); } class A extends B implements HasDoor { Door d; @Override public Door getDoor() { Door door = new Door() { public void open() { System.out.println("Open A's Door"); } public void close() { System.out.println("Close A's Door"); } }; return door; } 

    }

    La clase X extiende Y implementa HasDoor {Door d;

     @Override public Door getDoor() { Door door = new Door() { public void open() { System.out.println("Open X's Door"); } public void close() { System.out.println("Close X's Door"); } }; return door; } 

    }

    Clase B {} clase Y {}

Si no desea utilizar la interfaz HasDoor, puede declarar constructores dentro de la clase X y la clase A que inicializa la instancia de Puerta.

Ejemplo;

 class X extends Y { Door d; public X() { d = new Door() { public void open() { System.out.println("Open X's Door"); } public void close() { System.out.println("Close X's Door"); } }; } } 

Así que aquí su clase a y la clase a tiene que seguir las mismas funciones. Que es ambas clases tienen las mismas funciones.

Ya que las clases ya extendieron otra clase podemos usar la interfaz

 interface door { openDoor(){ } closeDoor(){ } } 

Tanto la clase a como x pueden implementar la interfaz de puerta. Introduzca aquí la descripción de la imagen

Una clase puede implementar cualquier número de interfaces, pero puede extender sólo una clase.

Si la implementación de la puerta de clase es la misma que podemos hacer de esta manera

 class Door { openDoor(){ impl// } closeDoor(){ impl// } } class A extends b { Door d=new Door(); d.opendoor(); d.closeDorr(); } 

Sí, cree una clase abstracta que contenga el código común. Haga que esta clase abstracta implemente una interfaz que contenga los métodos necesarios.

Haga que ambas clases extiendan la clase abstracta.

Creo que debe crear una interfaz con métodos openDoor () y closeDoor (). Después de eso heredar las clases A y X de esta interfaz e implementar métodos. Si la implementación de métodos es similar, puede crear una clase de utilidad con métodos estáticos.

 public interface YourInterface{ public void openDoor(); public void closeDoor(); } public abstract class YourAbstractClass implements YourInterface{ public abstract void openDoor(); public abstract void closeDoor(); } public class YourClass extends YourAbstractClass{ @Override public void openDoor(); public void closeDoor(); } public class YourSubClass extends YourClass{ //you can just call super methods here super.openDoor(); super.closeDoor(); } 
  • Cómo obtener la versión de la aplicación utilizando libgdx / robovm
  • Final int parámetro utilizado en Runnable anónimo
  • GcmListenerService.onMessageReceived () no se ha llamado
  • métodos en foreach y para bucles en java
  • JSONObject obtiene el valor del primer nodo independientemente del nombre
  • ¿Cuál debería ser el tiempo de espera de conexión estándar y el tiempo de espera del socket en android
  • Cómo analizar una cadena de cookies
  • Servicio androide con repetición de hilo en el fondo con el bloqueo parcial de la estela
  • Líneas de desplazamiento de borde azul de listview. Androide
  • Diseño de fragmentos: ¿Cómo adaptarse a múltiples diseños de pantalla mostrando / ocultando fragmentos dentro de una sola actividad?
  • La respuesta de Json es un android muy lento
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.