Establecer y Obtener Métodos en java?


¿Cómo puedo usar los métodos set y get, y por qué debo usarlos? Son realmente útiles? Y también me puede dar ejemplos de establecer y obtener métodos?

Author: Múna, 2011-07-10

15 answers

Los métodos Set y Get son un patrón de encapsulación de datos. En lugar de acceder directamente a las variables de los miembros de la clase, se definen get métodos para acceder a estas variables y set métodos para modificarlas. Al encapsularlos de esta manera, usted tiene control sobre la interfaz pública, en caso de que necesite cambiar el funcionamiento interno de la clase en el futuro.

Por ejemplo, para una variable miembro:

Integer x;

Usted podría tener métodos:

Integer getX(){ return x; }
void setX(Integer x){ this.x = x; }

chiccodoro también mencionó un punto importante. Si solo desea permitir el acceso de lectura al campo para cualquier clase extranjera, puede hacerlo proporcionando un método get público y manteniendo el set privado o no proporcionando un set en absoluto.

 51
Author: Justin Ethier,
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
2014-04-29 13:50:03

Quiero agregar a otras respuestas que los setters se pueden usar para evitar poner el objeto en un estado no válido.

Por ejemplo, supongamos que tengo que establecer un TaxId, modelado como una cadena. La primera versión del setter puede ser la siguiente:

private String taxId;

public void setTaxId(String taxId) {
    this.taxId = taxId;
}

Sin embargo, es mejor evitar el uso de establecer el objeto con un taxId inválido, por lo que podemos introducir una comprobación:

private String taxId;

public void setTaxId(String taxId) throws IllegalArgumentException {
    if (isTaxIdValid(taxId)) {
        throw new IllegalArgumentException("Tax Id '" + taxId + "' is invalid");
    }
    this.taxId = taxId;
}

El siguiente paso, para mejorar la modularidad del programa, es hacer que el TaxId en sí como un Objeto, capaz de para comprobarse a sí mismo.

private final TaxId taxId = new TaxId()

public void setTaxId(String taxIdString) throws IllegalArgumentException {
    taxId.set(taxIdString); //will throw exception if not valid
}

Del mismo modo para el getter, ¿qué pasa si no tenemos un valor todavía? Tal vez queremos tener un camino diferente, podríamos decir:

public String getTaxId() throws IllegalStateException {
    return taxId.get(); //will throw exception if not set
}
 21
Author: stivlo,
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
2014-12-10 14:12:38

Creo que quieres algo como esto:

public class Person {

  private int age;

  //public method to get the age variable
  public int getAge(){
       return this.age
  }

  //public method to set the age variable
  public void setAge(int age){
       this.age = age;
  }
}

Simplemente está llamando a dicho método en una instancia de objeto. Tales métodos son útiles especialmente si se supone que el establecimiento de algo tiene efectos secundarios. Por ejemplo, si desea reaccionar a ciertos eventos como:

  public void setAge(int age){

       this.age = age;

       double averageCigarettesPerYear = this.smokedCigarettes * 1.0 / age;

       if(averageCigarettesPerYear >= 7300.0) {
           this.eventBus.fire(new PersonSmokesTooMuchEvent(this));
       }
  }

Por supuesto, esto puede ser peligroso si alguien se olvida de llamar setAge(int) donde debería y establece age directamente usando this.age.

 8
Author: Stefan Falk,
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-09-04 13:53:39

Tener métodos de acceso es preferible a acceder a los campos directamente, porque controla cómo se accede a los campos (puede imponer la comprobación de datos, etc.) y se ajusta a las interfaces (las interfaces no pueden requerir que los campos estén presentes, solo los métodos).

 6
Author: Bohemian,
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
2011-07-10 03:24:53

Los setters y getters se usan para reemplazar variables miembro que acceden directamente desde clases externas. si utiliza un setter y un getter para acceder a una propiedad, puede incluir inicialización, comprobación de errores, transformaciones complejas, etc. Algunos ejemplos:

private String x;

public void setX(String newX) {
    if (newX == null) {
        x = "";
    } else {
        x = newX;
    }
}

public String getX() {
    if (x == null) {
        return "";
    } else {
       return x;
    }
}
 5
Author: g051051,
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
2011-07-10 03:25:42

Algunos beneficios de usar getters y setters (conocidos como encapsulation o data-hiding):

(originalmente respondida aquí )

1. Los campos de una clase se pueden hacer de solo lectura (solo proporcionando el getter) o de solo escritura (solo proporcionando el setter). Esto le da a la clase un control total de quién accede/modifica sus campos.

Ejemplo:

class EncapsulationExample {
    private int readOnly = -1;  // this value can only be read, not altered
    private int writeOnly = 0;    // this value can only be changed, not viewed
    public int getReadOnly() {
        return readOnly;
    }
    public int setWriteOnly(int w) {
        writeOnly = w;
    }
}

2. Los usuarios de una clase no necesitan para saber cómo la clase realmente almacena los datos. Esto significa que los datos están separados y existen independientemente de los usuarios, lo que permite que el código se modifique y mantenga más fácilmente. Esto permite a los mantenedores realizar cambios frecuentes como correcciones de errores, mejoras de diseño y rendimiento, todo sin afectar a los usuarios.

Además, los recursos encapsulados son uniformemente accesibles para cada usuario y tienen un comportamiento idéntico independiente del usuario, ya que este comportamiento es definido internamente en la clase.

Ejemplo (obtener un valor):

class EncapsulationExample {
    private int value;
    public int getValue() {     
        return value; // return the value
    }
}

Ahora, ¿y si quisiera devolver el doble del valor en su lugar? Solo puedo alterar mi getter y todo el código que está usando mi ejemplo no necesita cambiar y obtendrá el doble del valor:

class EncapsulationExample {
    private int value;
    public int getValue() {
        return value*2; // return twice the value
    }
}

3. Hace que el código sea más limpio, más legible y más fácil de comprender.

Aquí hay un ejemplo:

Sin encapsulación:

class Box {
    int widthS; // width of the side
    int widthT; // width of the top
    // other stuff
}

// ...
Box b = new Box();
int w1 = b.widthS;  // Hm... what is widthS again? 
int w2 = b.widthT;  // Don't mistake the names. I should make sure I use the proper variable here!

Con encapsulación:

class Box {
    private int widthS; // width of the side
    private int widthT; // width of the top
    public int getSideWidth() {
        return widthS;
    }
    public int getTopWIdth() {
        return widthT;
    }
    // other stuff
}

// ...
Box b = new Box();
int w1 = b.getSideWidth(); // Ok, this one gives me the width of the side
int w2 = b.getTopWidth(); // and this one gives me the width of the top. No confusion, whew!

Mira cuánto más control tienes sobre qué información estás obteniendo y cuánto más claro está esto en el segundo ejemplo. Tenga en cuenta, este ejemplo es trivial y en la vida real las clases que se trataría con una gran cantidad de recursos a los que se accede por muchos componentes diferentes. Por lo tanto, encapsular los recursos hace que sea más claro a cuáles estamos accediendo y de qué manera (obteniendo o configurando).

Aquí está good SO thread en este tema.

Aquí está good read en la encapsulación de datos.

 4
Author: nem035,
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
2017-05-23 12:18:12

Las respuestas anteriores resumen el papel de los getters y setters mejor de lo que pude, sin embargo, quería agregar que su código debería estructurarse idealmente para reducir el uso de getters y setters puros, es decir, aquellos sin construcciones complejas, validación, etc., ya que rompen la encapsulación. Esto no significa que nunca puedas usarlos (la respuesta de stivlo muestra un ejemplo de un buen uso de getters y setters), solo trata de minimizar la frecuencia con la que los usas.

El problema es que los getters y setters pueden actuar como una solución para el acceso directo a los datos privados. Los datos privados se llaman privados porque no están destinados a ser compartidos con otros objetos; están destinados como una representación del estado del objeto. Permitir que otros objetos accedan a los campos privados de un objeto anula todo el propósito de configurarlo privado en primer lugar. Además, introduce el acoplamiento para cada getter o setter que escriba. Considere esto, por ejemplo:

private String foo;

public void setFoo(String bar) {
    this.foo = bar;
}

¿Qué sucede si, en algún lugar abajo el camino, usted decide que no necesita foo más, o que desea que sea un entero? Cada objeto que usa el método setFoo ahora necesita ser cambiado junto con foo.

 2
Author: xobicvap,
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
2011-07-09 22:47:52

Solo porque la regla OOP: Ocultación de datos y Encapsulación. Es una muy mala práctica declarar un objeto como público y cambiarlo sobre la marcha en la mayoría de las situaciones. También hay muchas otras razones, pero la raíz es la encapsulación en OOP. y "compre un libro o vaya a leer sobre Programación Orientada a objetos", comprenderá todo sobre esto después de leer cualquier libro sobre OOP.

 2
Author: Ben Xu,
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
2011-07-10 03:41:16

Los beneficios de los métodos get() set() son los siguientes ..

  1. Puede serializar su objeto fácilmente.
  2. Puede crear un objeto persistente a partir de la clase contenedora.
  3. Puede convertir las propiedades a JSON fácilmente.
  4. En la capa DAO (Frameworks como Hibernate) puede guardar directamente el objeto en DB.
  5. Fácil comprensión del concepto orientado a objetos.
  6. Necesita en todo el patrón de diseño excepto posiblemente en el patrón de un solo tono.
  7. Seguridad para propiedades que protegen el acceso directo.
  8. Polimorfismo, Encapsulación puede ser fácilmente entendido e implementado por este tipo de clase.

Ejemplo:

private String personName;
private int personId;

    public void setPersonName(String name) throws Exception{
    if(!(name.equals("")||name=="")){
      this.personName = name;
    }
  }
  public String getPersonName(){
    return this.personName;
  }
  public void setPersonId(int id) throws Exception{
    this.personId = id;
  }
  public int getPersonId(){
    return this.personId;
  }
 1
Author: Kaisar,
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
2011-07-10 06:20:02

Todas las respuestas anteriores asumen que el objeto en cuestión es un objeto con comportamiento. Una estrategia avanzada en OOP es separar los objetos de datos (que hacen zip, solo tienen campos) y los objetos de comportamiento.

Con objetos de datos, está perfectamente bien omitir getters y en su lugar tener campos públicos. Por lo general, no tienen setters, ya que lo más común es que sean inmutables - sus campos se establecen a través de los constructores, y nunca más. Echa un vistazo a Bob Martin Código limpio o Pryce y Freeman's Creciendo Software OO... para más detalles.

 1
Author: Urs Reupke,
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
2011-07-10 07:27:58
public class Person{

private int age;

public int getAge(){
     return age;
}

public void setAge(int age){
     this.age = age;
}
}

Creo que esto es lo que quieres.. y esto también llamado pojo

 1
Author: subash,
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
2014-04-29 12:28:12

Este es el código para el método set

public void setAge(int age){
  this.age = age;
}
 0
Author: amit bhardwaj,
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
2014-04-29 12:28:00

Parece que intentas hacer algo similar a C# si quieres el método setAge create
setAge(int age){ this.age = age;}

 0
Author: user3455363,
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
2014-04-29 12:28:39

No veo una respuesta simple a la segunda pregunta (por qué) aquí. Así que aquí va.

Digamos que tiene un campo público que se usa muy a menudo en su código. Cada vez que usted decide que necesita hacer algo extra antes de dar o establecer este campo usted tiene un problema. Tienes que crear un getter y setter especial para este campo y cambiar tu código completo de usar el campo directamente a usar el getter y setters.

Ahora imagine que está desarrollando una biblioteca ampliamente utilizada por mucha gente. Cuando usted necesita hacer un cambio como el anterior y establecer el acceso directo del campo a privado el código de todas las personas que utilizan este campo se romperá.

El uso de getters y setters es sobre la planificación futura del código, lo hace más flexible. Por supuesto, puede usar campos públicos, especialmente para clases simples que solo contienen algunos datos. Pero siempre es una buena idea hacer que el campo sea privado y codificar un método get y set para él.

 0
Author: Madmenyo,
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
2014-08-26 10:58:42

Esta respuesta se fusiona de otra pregunta.

Su método getAge() se llama método de instancia en Java.

Para invocar un método de instancia, debe tener un objeto de la Clase en la que se define este método.

Por Ejemplo, Si este método en una Clase llamada Person, entonces

  1. Crear un objeto Person usando el nuevo operador

     Person p = new Person();
    
  2. Para obtener la antigüedad de un objeto Person, use este método

    p.getAge()
    
 0
Author: Abimaran Kugathasan,
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
2017-03-22 15:29:03