繁体   English   中英

java中的Set和Get方法?

[英]Set and Get Methods in java?

如何使用 set 和 get 方法,为什么要使用它们? 他们真的有用吗? 你能给我一些设置和获取方法的例子吗?

Set 和 Get 方法是数据封装的一种模式。 不是直接访问 class 成员变量,而是定义get方法来访问这些变量,并set方法来修改它们。 通过以这种方式封装它们,您可以控制公共接口,如果您将来需要更改 class 的内部工作方式。

例如,对于成员变量:

Integer x;

你可能有方法:

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

奇科多罗还提到了一个重要的点。 如果您只想允许对任何外部类的字段进行读取访问,则可以通过仅提供公共get方法并保持set私有或根本不提供set来实现。

我想添加其他答案,设置器可用于防止将 object 放入无效的 state 中。

例如,假设我必须设置一个 TaxId,建模为一个字符串。 setter 的第一个版本可以如下:

private String taxId;

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

但是我们最好避免使用无效的taxId设置object,所以我们可以引入一个检查:

private String taxId;

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

下一步,为了提高程序的模块化,将 TaxId 本身设置为 Object,能够自我检查。

private final TaxId taxId = new TaxId()

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

同样对于 getter,如果我们还没有值怎么办? 也许我们想要一条不同的路径,我们可以说:

public String getTaxId() throws IllegalStateException {
    return taxId.get(); //will throw exception if not set
}

我想你想要这样的东西:

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;
  }
}

您只是在 object 实例上调用这样的方法。 这些方法很有用,尤其是在设置某些东西应该有副作用的情况下。 例如,如果您想对某些事件做出反应,例如:

  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));
       }
  }

当然,如果有人忘记在他应该调用setAge(int)并直接使用this.age设置age ,这可能会很危险。

拥有访问器方法优于直接访问字段,因为它控制如何访问字段(可能会强制进行数据检查等)并适合接口(接口不能要求字段存在,只有方法)。

Setter 和 getter 用于替换从外部类直接访问成员变量。 如果您在访问属性时使用 setter 和 getter,则可以包括初始化、错误检查、复杂转换等。一些示例:

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;
    }
}

使用 getter 和 setter 的一些好处(称为encapsulationdata-hiding ):

(最初在这里回答)

1. class 的字段可以设为只读(仅提供 getter)或只写(仅提供 setter)。 这使 class 可以完全控制谁可以访问/修改其字段。

例子:

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. class 的用户不需要知道 class 实际是如何存储数据的。 这意味着数据是独立于用户而独立存在的,因此可以更轻松地修改和维护代码。 这允许维护人员进行频繁的更改,例如错误修复、设计和性能增强,同时不会影响用户。

此外,每个用户都可以统一访问封装的资源,并且具有独立于用户的相同行为,因为这种行为是在 class 内部定义的。

示例(获取值):

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

现在,如果我想返回两倍的值怎么办? 我可以更改我的 getter,并且使用我的示例的所有代码都不需要更改,并且将获得两倍的值:

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

3. 使代码更简洁、更易读、更容易理解。

这是一个例子:

无封装:

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!

带封装:

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!

看看在第二个示例中,您对获取哪些信息有多少控制权,以及这有多清晰。 请注意,这个例子是微不足道的,在现实生活中,您将处理许多不同组件访问的大量资源的类。 因此,封装资源使我们更清楚地访问哪些资源以及以何种方式(获取或设置)。

这是关于此主题的good SO thread

这是关于数据封装的good read

只是因为 OOP 规则:数据隐藏和封装。 在大多数情况下,将对象声明为公共并即时更改它是一种非常糟糕的做法。 还有很多其他原因,但根源在于OOP中的封装。 和“买一本书或 go 阅读 Object Oriented Programming ”,您将在阅读有关 OOP 的任何书籍后了解这方面的一切。

上面的答案比我更好地总结了 getter 和 setter 的作用,但是我确实想补充一点,理想情况下,您的代码应该结构化以减少纯 getter 和 setter 的使用,即那些没有复杂构造、验证等的代码,因为他们打破了封装。 这并不意味着你永远不能使用它们(stivlo 的回答显示了一个很好地使用 getter 和 setter 的例子),只是尽量减少你使用它们的频率。

问题是 getter 和 setter 可以作为直接访问私有数据的解决方法。 私有数据之所以称为私有数据,是因为它不打算与其他对象共享; 它表示对象的 state。 允许其他对象访问一个对象的私有字段会破坏首先将其设置为私有的整个目的。 此外,您为您编写的每个 getter 或 setter 引入耦合。 考虑一下,例如:

private String foo;

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

如果在某个地方,您决定不再需要 foo,或者您想让它成为 integer,会发生什么? 每个使用 setFoo 方法的 object 现在都需要与 foo 一起更改。

public class Person{

private int age;

public int getAge(){
     return age;
}

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

我想这就是你想要的……这也叫pojo

get() set() 方法的好处如下。

  1. 您可以轻松地序列化您的 object。
  2. 您可以从包含的 class 创建持久 object。
  3. 您可以轻松地将属性转换为 JSON。
  4. 在 DAO 层(Hibernate 等框架)中,您可以直接将 object 保存到 DB。
  5. 易于理解 object 面向概念。
  6. 需要在所有设计模式中,但可能在单色调模式中除外。
  7. 保护直接访问的属性的安全性。
  8. 多态性、封装性可以通过这种类型的 class 轻松理解和实现。

例子:

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;
  }

以上答案都假设有问题的 object 是具有行为的 object。 OOP 中的一个高级策略是将数据对象(即 zip,只有字段)和行为对象分开。

对于数据对象,省略 getter 并使用公共字段是完全可以的。 它们通常没有设置器,因为它们通常是不可变的——它们的字段是通过构造函数设置的,并且永远不会再设置。 请查看 Bob Martin 的Clean Code或 Pryce 和 Freeman 的成长型 OO 软件...了解详细信息。

这个答案是从另一个问题合并而来的。

您的getAge()方法在 Java 中称为实例方法。

要调用实例方法,您应该拥有定义此方法的 Class 的 object。

例如,如果此方法在 Class 中称为Person ,则

  1. 使用 new 运算符创建人员 object

     Person p = new Person();
  2. 要获取Person object 的年龄,请使用此方法

    p.getAge()

这是设置方法的代码

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

如果您想要 setAge 创建方法,您似乎正在尝试做类似于 C# 的事情
setAge(int age){ this.age = age;}

我在这里看不到第二个问题(为什么)的简单答案。 所以这里。

假设您有一个在您的代码中经常使用的公共字段。 每当您决定在提供或设置此字段之前需要做一些额外的事情时,您就会遇到问题。 您必须为此字段创建一个特殊的 getter 和 setter,并将您的完整代码从直接使用该字段更改为使用 getter 和 setter。

现在想象一下,您正在开发一个被许多人广泛使用的库。 当您需要进行上述更改并将该字段的直接访问设置为私有时,所有使用该字段的人的代码都会中断。

使用 getter 和 setter 是关于代码的未来规划,它使其更加灵活。 当然,您可以使用公共字段,尤其是对于仅包含一些数据的简单类。 但是,将字段设为私有并为其编写 get 和 set 方法总是一个好主意。

虽然还是本科二年级的学生我来说说我的看法。 我相信 Java 和 class 中的私有变量是“规则”。 因此,因为 class 中的变量是私有的,我认为您使用 getter 和 setter 能够在 class 之外定义这些变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM