Saltar al contenido

¿Cómo forzar subclases para establecer una variable en java?

Es importante entender el código bien previamente a adaptarlo a tu proyecto si ttienes algo que aportar puedes compartirlo con nosotros.

Solución:

El comentario de @pst conduce a esta solución.

Esto no se puede hacer con una variable. Pero una clase abstracta puede requerir que se implemente un método particular: este método podría devolver el valor aplicable

De declarar un abstract para establecer o devolver la variable, puede obligar a cualquier subclase a implementarla correctamente.

A continuación, la función debe ser llamada por cada subclase de la clase externa. Esto implica que debe hacerse en algún lugar de la clase externa. Esto se puede hacer en el constructor sin argumentos de la clase externa sin tener que preocuparse por las subclases que llaman super:

Nota: si un constructor no invoca explícitamente a un constructor de superclase, el compilador de Java inserta automáticamente una llamada al constructor sin argumentos de la superclase. Si la superclase no tiene un constructor sin argumentos, obtendrá un error de tiempo de compilación. Object tiene dicho constructor, por lo que si Object es la única superclase, no hay problema. (Documentos de Java: Súper)

Basado en eso, esta solución se mantendrá y correctamente fuerza la variable que se establecerá siempre que:

  1. No se crea ningún otro constructor en la superclase (por lo tanto, super no se puede usar en una subclase para llamar a un constructor diferente en su lugar)
  2. Todos los demás constructores de la superclase siguen llamando internamente al constructor predeterminado.

El código:

Superclase:

public abstract class SuperClass 
    // Variable all inner classes must set
    static int myVar = 0;

    public SuperClass() 
        myVar = giveValue();
    

    public abstract int giveValue();

Subclase:

public class SubClass extends SuperClass 

    @Override
    public int giveValue() 
        return 5; // individual value for the subclass
    


En lugar de imponer que las instancias de clase secundaria inicialicen los campos, puede seguir una estrategia de composición haciendo que el constructor de su clase principal tome un parámetro que implemente una interfaz que proporcione los campos que desea inicializar.

class Screen 
  final Configuration config;
  Screen(Configuration config) 
    this.config = config;
  
  // or
  Screen(ConfigFactory configFactory) 
    this.config = configFactory.make();
  


interface ConfigFactory 
  Configuration make();

Le advertiría que no requiera una instancia de subclase que inicialice la configuración, por ejemplo, usando una implementación de método abstracto. La asignación en el constructor de la clase principal ocurre antes de que se inicialice la instancia de la subclase, implícitamente realizar el cálculo adecuado de la configuración static.

Si el cálculo no es statica tu riesgo null referencias o NullPointerExceptions de los desarrolladores que lo siguen (o usted mismo si su memoria no es perfecta). Haz que sea más fácil para tus colaboradores (y para ti mismo) y haz explícitas las restricciones.

Como mencionó @Ketan en la respuesta de @BT, invocar un método anulable del constructor no es especialmente una buena práctica (https://help.semmle.com/wiki/display/JAVA/Non-final+method+invocation+in+constructor )

Una forma de evitar este problema consiste en tener un captador abstracto (protegido) para el campo. Por lo tanto, la superclase ya no tiene el campo, pero aún se puede acceder a él en la superclase mediante el getter. Cada subclase se ve obligada a declarar el campo porque debe anular el captador abstracto.

Superclase:

public abstract class SuperClass 

  public SuperClass() 

  protected abstract int getMyVar();

  public void functionUsingMyVar()
     int a = 12 + getMyVar();
  

Subclase1:

public class SubClass1 extends SuperClass 

  private int myVar;

  public SubClass1() 
     super();
     myVar = 1;
  

  @Override
  protected int getMyVar()
     return myVar;
  


Subclase2:

 public class SubClass2 extends SuperClass 

  private int myVar;

  public SubClass2() 
     super();
     myVar = 1;
  

  @Override
  protected int getMyVar()
     return myVar;
  


en lugar de tener para la superclase (donde giveValue() se anula y se llama en el constructor):

public abstract class SuperClass 

  private int myVar;

  public SuperClass() 
     myVar = giveValue();
  

  protected abstract int giveValue();

  public void functionUsingMyVar()
     int a = 12 + myVar;
  

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *