¿Cómo evitar la herencia múltiple en Java

user3617992:

Estoy en una situación en la que estoy tratando de poner en práctica un árbol sintáctico (relativamente simple) abstracto. Todos los nodos heredan de un tipo llamado SimpleNode que contiene un código de línea de la tienda y la información de la columna y la aceptación de un visitante.

Ahora, algunos de los nodos También debe haber nominable, mientras que otros deben tener una propiedad "accesible" (por ejemplo., Pública o privada). Algunos nodos deben soportar incluso las dos interfaces.

Me implementar esta preferencia mediante la herencia virtual y escribir dos clases NameableNode y AccessibleNode, pero Java no soporta MI.

Por ejemplo, podría tener NameableNode campo "Nombre" y poner en práctica captadores y definidores simples para este campo. Del mismo modo, AccessibleNode también podría tener un campo "accesibilidad" y getters / setters.

¿Qué es una buena manera de implementar esto y evitar la introducción de la duplicación de código en una gran parte de la base de código?

Pequeño ejemplo de código:

public class SimpleNode {
    private int line = 0;
    private int column = 0;

    /* Getters and setters for line/column. */
    /* ... */
}

public class NameableNode extends SimpleNode {
    private String name = "";

    /* Getters and setters for name */
}

public class AccessibleNode extends SimpleNode {
    private boolean isPublic = false;

    /* Getters and setters for accessibility */
}
kenny_k:

Usted está buscando composición . Hay muchos sabores de esta - Voy a proponer que, desde mi comprensión de lo que están tratando de construir, debe adaptarse a su propósito.

En primer lugar, vamos a crear algunas interfaces para la suya Nodes:


public interface Nameable {
    /* Getters and setters for name */
}

public interface Accessible {
     /* Getters and setters for accessibility */
}

A continuación, es probable que no quiere repetir el mismo para cada aplicación Node, por lo que vamos a crear esas implementaciones:


public class NameDelegate() {
    private String name = "";

    /* Getters and setters for name */    
}

public class AccessDelegate() {
    private boolean isPublic = false;

    /* Getters and setters for accessibility */

}

Ahora, vamos a poner todo junto:

public class SomeNodeA extends SimpleNode implements Nameable {

   private NameDelegate nameDelegate;

   public SomeNodeA(NameDelegate nameDelegate) {
      this.nameDelegate = nameDelegate;
   }

   @Override
   public String getName() {
       return nameDelegate.getName();
   }

   @Override
   public String setName(String name) {
       nameDelegate.setName(name);
   }
}

También puede hacer que ambos comportamientos en una sola clase:

public class SomeNodeB extends SimpleNode implements Nameable, Accessible {

   private NameDelegate nameDelegate;
   private AccessDelegate accessDelegate;

   public SomeNodeB(NameDelegate nameDelegate, AccessDelegate accessDelegate) {
      this.nameDelegate = nameDelegate;
      this.accessDelegate = accessDelegate;
   }

   @Override
   public String getName() {
       return nameDelegate.getName();
   }

   @Override
   public String setName(String name) {
       nameDelegate.setName(name);
   }

   @Override
   public boolean getAccessibility() {
       return accessDelegate.getAccessibility();
   } 

    /* etc... */
}

La idea es, puede empaquetar el estado y la funcionalidad de los diferentes "características" en los delegados individuales, y exponerlos como interfaces correspondientes en sus nodos.

Además, cuando se opera en los Nodes, si lo que necesita saber si una instancia determinada de un Nodeadmite una función específica, se puede utilizar instanceof- por ejemplo:

if (someNode instanceof Nameable) {
   // do naming stuff
}

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=314070&siteId=1
Recomendado
Clasificación