sobrecarga que polimorfismo operadores métodos metodos ejercicios constructores conclusion java constructor overloading constructor-overloading

que - Sobrecarga de constructor en Java: mejor práctica



sobrecarga de metodos c# (5)

Bueno, aquí hay un ejemplo para constructores sobrecargados.

public class Employee { private String name; private int age; public Employee() { System.out.println("We are inside Employee() constructor"); } public Employee(String name) { System.out.println("We are inside Employee(String name) constructor"); this.name = name; } public Employee(String name, int age) { System.out.println("We are inside Employee(String name, int age) constructor"); this.name = name; this.age = age; } public Employee(int age) { System.out.println("We are inside Employee(int age) constructor"); this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }

En el ejemplo anterior, puede ver constructores sobrecargados. El nombre de los constructores es el mismo, pero cada constructor tiene diferentes parámetros.

Aquí hay algunos recursos que arrojan más luz sobre la sobrecarga del constructor en java,

Constructors

Explicación del constructor

Hay algunos temas similares a esto, pero no pude encontrar uno con una respuesta suficiente.

Me gustaría saber cuál es la mejor práctica para la sobrecarga de constructores en Java. Ya tengo mis propios pensamientos sobre el tema, pero me gustaría escuchar más consejos.

Me refiero tanto a la sobrecarga del constructor en una clase simple como a la sobrecarga del constructor mientras se hereda una clase ya sobrecargada (lo que significa que la clase base tiene constructores sobrecargados).

Gracias :)


Creo que la mejor práctica es tener un único constructor primario al que los constructores sobrecargados se refieren llamando a this() con los parámetros predeterminados relevantes. La razón de esto es que hace que esté mucho más claro cuál es el estado construido del objeto: realmente se puede pensar en el constructor primario como el único constructor real , los otros simplemente delegar en él

Un ejemplo de esto podría ser JTable : el constructor primario toma un TableModel (más modelos de columna y selección) y los otros constructores llaman a este constructor primario.

Para subclases donde la superclase ya tiene constructores sobrecargados , tendería a suponer que es razonable tratar como primarios a cualquiera de los constructores de la clase padre y creo que es perfectamente legítimo no tener un único constructor primario. Por ejemplo, cuando extiendo Exception , a menudo proporciono 3 constructores, uno solo toma un mensaje String , uno toma una causa Throwable y el otro toma ambos. Cada uno de estos constructores llama super directamente.


Realmente depende del tipo de clases, ya que no todas las clases se crean iguales.

Como directriz general, sugeriría 2 opciones:

  • Para las clases de valor e inmutables (Excepción, Entero, OTD y demás) use un solo constructor primario como se sugiere en la respuesta anterior
  • Para todo lo demás (beans de sesión, servicios, objetos mutables, entidades JPA y JAXB, etc.) use el constructor predeterminado solo con los valores predeterminados en todas las propiedades para que pueda usarse sin configuración adicional

Si bien no existen "pautas oficiales", sigo el principio de KISS y DRY. Haga que los constructores sobrecargados sean lo más simples posible, y la forma más simple es que solo llamen a esto (...). De esta forma, solo necesita verificar y manejar los parámetros una sola vez.

public class Simple { public Simple() { this(null); } public Simple(Resource r) { this(r, null); } public Simple(Resource r1, Resource r2) { // Guard statements, initialize resources or throw exceptions if // the resources are wrong if (r1 == null) { r1 = new Resource(); } if (r2 == null) { r2 = new Resource(); } // do whatever with resources } }

Desde el punto de vista de la unidad de evaluación, será más fácil probar la clase ya que puede poner los recursos en ella. Si la clase tiene muchos recursos (o colaboradores, como algunos OO-geeks lo llaman), considere una de estas dos cosas:

Haz una clase de parámetro

public class SimpleParams { Resource r1; Resource r2; // Imagine there are setters and getters here but I''m too lazy // to write it out. you can make it the parameter class // "immutable" if you don''t have setters and only set the // resources through the SimpleParams constructor }

El constructor en Simple solo necesita dividir el parámetro SimpleParams :

public Simple(SimpleParams params) { this(params.getR1(), params.getR2()); }

... o hacer de SimpleParams un atributo:

public Simple(Resource r1, Resource r2) { this(new SimpleParams(r1, r2)); } public Simple(SimpleParams params) { this.params = params; }

Hacer una clase de fábrica

Haga una clase de fábrica que inicialice los recursos para usted, lo cual es favorable si la inicialización de los recursos es un poco difícil:

public interface ResourceFactory { public Resource createR1(); public Resource createR2(); }

El constructor se hace de la misma manera que con la clase de parámetro:

public Simple(ResourceFactory factory) { this(factory.createR1(), factory.createR2()); }

Haz una combinación de ambos

Sí ... puedes mezclar y combinar las dos formas dependiendo de lo que sea más fácil para ti en ese momento. Las clases de parámetros y las clases simples de fábrica son prácticamente las mismas considerando que las clases Simple se usan de la misma manera.


Si tiene una clase muy compleja con muchas opciones de las cuales solo algunas combinaciones son válidas, considere usar un Constructor. Funciona muy bien tanto por código como también lógicamente.

The Builder es una clase anidada con métodos diseñados solo para establecer campos, y luego el constructor ComplexClass solo toma dicho constructor como argumento.

Editar: el constructor ComplexClass puede garantizar que el estado en el Generador sea válido. Esto es muy difícil de hacer si solo usa setters en ComplexClass.