Métodos de Setter o constructores


Hasta ahora he visto dos enfoques de establecer el valor de una variable en Java. A veces se utiliza un constructor con argumentos, otros métodos setter se utilizan para establecer el valor de cada variable.

Sé que un constructor inicializa una variable de instancia dentro de una clase una vez que una clase es instanciada usando la palabra clave "new".

Pero ¿cuándo usamos constructores y cuándo usamos setters?

Author: chŝdk, 2013-10-14

10 answers

Debe usar el enfoque constructor, cuando desee crear una nueva instancia del objeto, con los valores ya poblados(un objeto listo para usar con valor poblado). De esta manera no necesita sentarse explícitamente y llamar a los métodos setter para cada campo en el objeto para rellenarlos.

Se establece el valor utilizando un enfoque setter, cuando se desea cambiar el valor de un campo, después de que el objeto ha sido creado.

Por ejemplo:-

MyObject obj1 = new MyObject("setSomeStringInMyObject"); // Constructor approach
// Yippy, I can just use my obj1, as the values are already populated
// But even after this I can change the value
obj1.setSomeString("IWantANewValue"); // Value changed using setter, if required.
..
MyObject obj2 = new MyObject();
obj2.setSomeString("setSomeStringNow"); // Setter approach
// values weren't populated - I had to do that. Sad :(

Y como Axel mencionado, si desea crear objetos inmutables, no puede usar el enfoque setter-methods. No diré que todo tiene que ser inicializado en el constructor porque existen diferentes enfoques, como la evaluación perezosa que se puede usar incluso con objetos inmutables .

 32
Author: SudoRahul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-14 12:03:10

Si desea tener una clase inmutable use constructor de lo contrario use setters.

 3
Author: Evgeniy Dorofeev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-14 11:54:07

Digamos que tenemos una clase, llamada Counter:

public class Counter{
    int count;
    //constructor
    public Counter(int c){
        count = c;
    }
    public void setCounter(int newCounter){
        count = newCounter;
    }
}

En la clase anterior, cuando desee crear un nuevo Objeto Contador, utilizaría un constructor y establecería la variable count dentro de ese. así:

Counter myCounter = new Counter(1);

Si desea cambiar la variable count durante el tiempo de ejecución , debe usar el método setter:

myCounter.setCounter(2);
 2
Author: hmir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-14 11:56:39

Creo que hiciste una buena pregunta: - Pero ¿cuándo usamos constructores y cuándo usamos setters?

Primero, comencemos con algunos conceptos. Espero que esta explicación ayude a todos los que quieran saber cuándo usar los métodos constructores o setters () y getters () (Accessors y Mutators). Constructores son similares a Métodos, sin embargo, hay pocas diferencias entre constructor y método en java:

1) Constructor se utiliza para inicializar el estado de un objeto. Método se utiliza para exponer el comportamiento de un objeto.

2) Constructor no debe tener tipo de devolución. Método debe tener tipo de retorno.

3) Constructor se invoca implícitamente. Método se invoca explícitamente.

4) Getters(), o accesores, son métodos que proporcionar acceso a las variables de instancia de un objeto. Setters(), o mutadores, son métodos que brindan al llamante la oportunidad de actualizar el valor de una variable de instancia en particular.

Teniendo esto claro, pensemos en términos de Programación Orientada a Objetos (OOP), para cumplir con el requisito de los principios de OOP (La Programación Orientada a Objetos (OOP) se construye sobre cuatro principios principales: Encapsulación , la Abstracción de Datos, Polimorfismo y la Herencia.), Getter() y Setter() métodos es la clave para lograr esto.

Aquí hay una fórmula que te va a mostrar lo que quiero decir:

Campos privados + accesos públicos = = Encapsulación;

Como puedes ver basado en esta fórmula cuando establecemos campos privados y usamos accesorios públicos estamos realizando encapsulación uno de los 4 OOP principal.

Aquí voy a ofrecer dos clases, he añadido los comentarios para intentar hacer mi código autoexplicativo. Tome estas clases como un laboratorio sobre métodos con Customer y TestCustomer [el que tiene el método main()] clases, puede copiar el código y ejecutarlo usted mismo. Nota: Utilicé dos constructores para explicar una clase que tiene varios constructores y que tiene métodos públicos setters() y getters() para acceder a variables de instancia privadas:

package com.exercise.lecture2;

/**
 * 1) Create a Customer class that has the following attributes:
 * name, SSN.
 * 2) This class should have two methods: getName() and getSSN().
 * 3) If the class is instantiated with only a SSN, then give the default name of "John Doe". (HINT: Use two constructors)
 * 4) Also, add a method toString(), that returns a string representation of the customer object (name and SSN concatenated).
 *      Make sure to set this method public.
 * 5) Create a class to test your program (e.g. a class that include the main() method). In your test program, instantiate
 *      three customers and print out the value using toString() method.
 * 
 * @author Samuel M.
 *
 */

//this class is complemented with class  TestLabCustomer.java
public class LabCustomer {

// Private filds: name and socialSecurityNum
    private String name;
    private int socialSecurityNum;

    // constructors
    public LabCustomer(String name, int socialSecurityNum) {
        this.name = name;
        this.socialSecurityNum = socialSecurityNum;
    }

    /** The keyword 'this' can be used to call a constructor from a constructor,
     * when writing several constructor for a class, there are times when
     * you'd like to call one constructor from another to avoid duplicate code.
     */
    // Account with This() on a second constructor
    public LabCustomer(int socialSecurityNum) {
        this("John Doe", socialSecurityNum); // default name is printed if only the SSN is provided
    }

    // Public accessors (getters and setters)
    String getName() {
        return name;
    }

    void setName(String name) {
        this.name = name;
    }

    int getSSN() {
        return socialSecurityNum;
    }

    void setSSN(int socialSecurityNum) {
        this.socialSecurityNum = socialSecurityNum;
    }


    // instance method
    public String toString() { //overriding the toString() method 
        return ("Customer name: " + getName() + ", SSN#: " + getSSN() ); // concatenating the name and SSN

    }
}

Aquí está la clase de prueba, la que tiene el método main() y llama a un método instance después de instanciar un objeto de la clase previews:

package com.exercise.lecture2;

//this class is complemented with class  LabCustomer.java
public class TestLabCustomer {

    public static void main(String[] args) {
        // Instantiating an object of class LabCustomer and creating three customers objects
        LabCustomer cust1 = new LabCustomer("Juan Melendez", 123457789);
        LabCustomer cust2 = new LabCustomer("Mary Lee", 125997536);
        LabCustomer cust3 = new LabCustomer(124963574); // when instantiating with no "name", the default (John Doe) is printed 

        /**
         * Once you've instantiated an object and have an object variable,
         * you can use object variable to call an instance method. 
         *  e.g.:
         *  object variables: cust1, cust2, cust3
         *  call the method toString() using the object variable and dot [.] in order to perform the method call.
         */
        // calling method toString() in class LabCustomer to print customer values
        System.out.println(cust1.toString());
        System.out.println(cust2.toString());
        System.out.println(cust3.toString());

    }

}

resultado:

Nombre del cliente: Juan Meléndez, SSN#: 123457789

Nombre del cliente: Mary Lee, SSN#: 125997536

Nombre del cliente: John Doe, SSN#: 124963574

 2
Author: S. Mayol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-06 18:46:41

Utilizamos el enfoque dependiendo del escenario.

  1. Si tenemos un conjunto de valores mientras instanciamos el objeto de la clase, entonces en ese momento usaremos el enfoque constructor.

  2. Cuando no conocemos el conjunto de valores mientras creamos la instancia del objeto en ese momento usaremos el enfoque setter.

 1
Author: eatSleepCode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-14 12:00:15

En la mayoría de los casos utilizo ambos:) (ya que 9/10 veces quieres volver y editar algo (y eso no es una buena práctica para hacer una nueva instancia de ello)

Normalmente hago algo como tihs

public class User {

    private int id;
    private String initials;
    private String firstName;
    private String lastName;
    private String email;

    public User() {
        this(0, "", "", "");
    }

    public User(int id, String firstName, String lastName, String email) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }
   // Getters and setters should be here
}

Y cuando quieras editar algo con él, puedes usar los setters, (una buena cosa si, por ejemplo, guardas a tus usuarios en una ArrayList, entonces puedes obtener el objeto de la arraylist y simplemente establecer el campo que quieres editar, en lugar de hacer una nueva objeto de la misma:)

 1
Author: Kasper Franz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-14 12:02:26

Depende del dominio de la aplicación y el propósito de la clase en ella.

Java beans normalmente tiene un constructor no arg y getter/setters para las variables de miembro relevantes. Hay ventajas en este enfoque, ya que los Java beans son compatibles desde el primer momento en muchos frameworks como Struts y Spring.

Una clase también puede imponer la disponibilidad obligatoria de valores haciendo que dichas variables se pasen como parámetros a un constructor base. Y los valores no obligatorios se pueden establecer a través de otros constructores de conveniencia o métodos setter.

Por otro lado, las clases inmutables pueden tener constructores, pero requieren métodos de ausencia que modifican su estado, incluidos los setters.

En general, tales decisiones pueden tomarse teniendo en cuenta el diseño general de la aplicación, los marcos1 se ejecuta en, contrato que debe hacer cumplir, etc.

1 - Aunque, se recomienda que el diseño de clases debe ser independiente de los marcos. Buenos marcos como Spring no hacen cumplir tales requisito.

 1
Author: sgp15,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-14 12:16:08

En el caso de los constructores, cuando actualizas los campos, creas un nuevo objeto cada vez usando la palabra clave new.

Customer customer = new Customer("Tom", 23, 10000);

Por ejemplo, si desea actualizar el salario de Tom, debe escribir esta línea nuevamente con el salario actualizado, lo que significa que se desperdicia memoria.

En el caso de los métodos setter, puede establecer campos individuales solo en el objeto original.

 1
Author: Sushil kumawat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-21 15:01:57

Puede combinar los dos aproximaciones. Dentro del constructor puede invocar los setters de las variables de instace. Algo como:

public class TestClass {
    private String someField;

    public TestClass(String someField) {
        setSomeField(someField);
    }

    public String getSomeField() {
        return someField;
    }

    public void setSomeField(String someField) {
        this.someField = someField;
    } 
}
 0
Author: Cold,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-14 11:53:11

En términos simples:

Use constructor si cree que la inicialización del objeto es obligatoria antes de usar el objeto.

Use el método setter cuando la inicialización de la variable no es obligatoria para usar el objeto.

Consulte la página de documentación para más detalles.

 0
Author: Ravindra babu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-06 18:58:02