Java 中的 Get 和 Set 方法。它们是如何工作的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9968682/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 23:06:28  来源:igfitidea点击:

Get and Set methods in Java. How do they work?

javaoop

提问by dwwilson66

I'm trying to get a better understanding than I've been able to so far...it's to help me with class, but not with any specific homework assignment; I'm looking for more conceptual information that I've not found in my textbook or in the tutorials. On a purely theoretical level, I get why encapsulation is powerful for OO programming, but need a better understanding of what, specifically is going on. I keep confusing myself about the path through which data flows, and wonder where we're getting and setting data FROM. Hopefully this is not the exception to the "there are no stupid questions" rule.

我试图获得比迄今为止更好的理解……这是为了帮助我上课,但不是任何特定的家庭作业;我正在寻找在我的教科书或教程中找不到的更多概念性信息。在纯粹的理论层面上,我明白为什么封装对于 OO 编程是强大的,但需要更好地理解具体发生了什么。我一直对数据流经的路径感到困惑,并想知道我们从哪里获取和设置数据。希望这不是“没有愚蠢的问题”规则的例外。

Consider:

考虑:

 public class Employee
 {
    private int empNum;
    public int getEmpNum()
    {   return empNum;   }
    public void setEmpNum(int Emp)
    {   empNum = emp;   }
 }

My interpretation of this: Using int Emppassed from somewhere, we set the declared empNum variable in the set...method. We then get...that variable and return it to the calling method. Is that a good understanding?

我对此的解释:使用int Emp从某处传递,我们在set...方法中设置了声明的 empNum 变量。然后我们get...将该变量返回给调用方法。这是一个很好的理解吗?

Further Consider:

进一步考虑:

import.javax.*
public class CreateEmp
{
    public static void main(String[] args)
    {
         int ssn;
         ssn = JOptionPane.showInputDialog(null,"enter ssn");
         Employee newEmp = new Employee(123456789);
         JOptionPane.showMessageDialog(null,"Employee ID " + newEmp.getEmpNum);
     }
 }

With this class, I don't need to explicitly seta variable because declaring new Employee(123456789)automagically sends that value to the set...method. The returnin the Employee method returns the resulting value to the calling method and makes that variable available, in this case to my dialog box output. Do I have a handle on that?

使用这个类,我不需要显式set变量,因为声明会new Employee(123456789)自动将该值发送给set...方法。将return在Employee方法返回的结果值调用方法,使该变量可用,在这种情况下我的对话框输出。我有把握吗?

Here's where I get confused. With my understanding as noted above--which may be off--I can never decide the best place to put logic. For instance: I would place the "enter employee number" dialog box in the Employeeclass, with a condition to run ONLY if the parameter passed to the method was null. In my mind, as I understand the data flow, the purpose of the class is to get an employee number. If one is not supplied as a default, one needs to be created. I'm not sure if this thinking is best practices, or if I'm setting myself up for trouble later.

这就是我感到困惑的地方。根据我上面提到的理解——这可能是错误的——我永远无法决定放置逻辑的最佳位置。例如:我会在Employee类中放置“输入员工编号”对话框,条件是仅当传递给方法的参数为空时才运行。在我看来,根据我对数据流的理解,该类的目的是获取员工编号。如果未提供一个作为默认值,则需要创建一个。我不确定这种想法是否是最佳实践,或者我是否会在以后给自己惹麻烦。

I'd love to hear some thoughts about whether or not I'm properly understanding what's happening.

我很想听听关于我是否正确理解正在发生的事情的一些想法。

回答by John Haager

The point of using public accessors for private variables is to control how those variables are accessed and to insure that all of the internal state is kept consistent. For example, a class might have both an ageand a birthdatevariable. Setting the birthdatealso implicitly sets the age. If direct access was given to these variables, then it would be possible to set them to inconsistent values (i.e. birthday says they are 30, but age set to 35). By using setters, we can insure that setting the birthdate will reset the age to be correct.

对私有变量使用公共访问器的目的是控制如何访问这些变量并确保所有内部状态保持一致。例如,一个类可能同时具有age一个birthdate变量和一个变量。设置 thebirthdate也隐式设置年龄。如果直接访问这些变量,则可以将它们设置为不一致的值(即生日说它们是 30,但年龄设置为 35)。通过使用 setter,我们可以确保设置生日会将年龄重置为正确的。

In this example, using setters would also allow us to convert the agevariable into a generated property. Since age can be directly determined using the birthdate, you can create a getter for ageand have it directly calculate and return the age without needing to store it anywhere.

在这个例子中,使用 setter 还允许我们将age变量转换为生成的属性。由于可以使用 直接确定年龄birthdate,因此您可以为其创建一个 getterage并让它直接计算并返回年龄,而无需将其存储在任何地方。

If we use getters and setters to expose these object properties, we are free to switch out the implementations (such as removing the agevariable and calculating it on the fly) without the users of our object needing to worry about it.

如果我们使用 getter 和 setter 来公开这些对象属性,我们可以自由地切换实现(例如删除age变量并动态计算它),而我们对象的用户无需担心它。

回答by jhenderson2099

It depends how you are using the Employee object. If, upon construction, you always provide the employee number or one is automatically provided and the employee number is never set anywhere else, then you won't need the set method.

这取决于您如何使用 Employee 对象。如果在构建时始终提供员工编号,或者自动提供员工编号并且员工编号从未在其他任何地方设置,那么您将不需要 set 方法。

However, if at some point you are going to set the employee number to something else (perhaps an error was made and the number needs to be updated), then you will need to have a "set" method. In this case, it would probably be easiest to also call the "set" method from the constructor.

但是,如果在某个时候您要将员工编号设置为其他内容(可能出现错误并且需要更新该编号),那么您将需要有一个“设置”方法。在这种情况下,从构造函数调用“set”方法可能是最简单的。

It really depends on how the Employee class will be used/instantiated.

这实际上取决于 Employee 类将如何使用/实例化。

回答by Martin Tuskevicius

First, this site is to be used more for questions that can be concretely answered; not so much for theoretical questions.

第一,本站更多用于可以具体回答的问题;对于理论问题来说不是那么多。

Anyways, the first part with the 'get' and 'set' you understand fine. Now when you said that you do not need to explicitly set the employee number because you do 'new Employee ...' is not quite true. That would work if you had explicitly defined a constructorthat takes an integer for an argument and then sets 'empNum' equal to the argued integer value.

无论如何,第一部分的“get”和“set”你理解得很好。现在,当您说您不需要明确设置员工编号时,因为您执行“新员工...”并不完全正确。如果您明确定义了一个构造函数,该构造函数将一个整数作为参数,然后将 'empNum' 设置为等于争论的整数值。

Getters and setters are usually used in conjunction with the 'private' modifier. Setters can be used to control the input. For example, you can check if the provided value is greater than zero, where as you cannot if you give direct access. Getters just allow values to be retrieved, but to make changes you force the use of the corresponding setter (if any).

getter 和 setter 通常与“private”修饰符结合使用。设置器可用于控制输入。例如,您可以检查提供的值是否大于零,而如果您提供直接访问权限,则无法检查。Getter 只允许检索值,但要进行更改,您将强制使用相应的 setter(如果有)。

You are right about how if a value is not supplied you should set one by default. Consider that the value that you retrieve (if any) is to be used in a different class. What if the user never set a value? What if it's not something you expected? The different class, whatever it may be, still requires a value and you still need to pass something. By setting a default value, the different class can recognize that, "oh, this is a default value - this means that the user probably did not supply the correct input." By doing so, you create a relatively fail-safe application; you can keep on working even if the input is not what it is expected to be.

如果未提供值,您应该如何默认设置一个值,这是正确的。考虑您检索的值(如果有)将在不同的类中使用。如果用户从不设置值怎么办?如果这不是您所期望的怎么办?不同的类,不管它是什么,仍然需要一个值,你仍然需要传递一些东西。通过设置默认值,不同的类可以识别,“哦,这是一个默认值——这意味着用户可能没有提供正确的输入。” 通过这样做,您可以创建一个相对故障安全的应用程序;即使输入不是预期的,您也可以继续工作。

回答by Simeon Visser

You say

你说

With this class, I don't need to explicitly set a variable because declaring new Employee(123456789) automagically sends that value to the set... method.

使用这个类,我不需要显式设置变量,因为声明 new Employee(123456789) 会自动将该值发送到 set... 方法。

I'm pretty sure that's not true. Consider this: Java creates an Employee object and the constructor receives the value 123456789. How does it know to which variable it needs to assign that value? It doesn't know. There can be multiple variables that belong to that object so it doesn't know what 123456789really means.

我很确定那不是真的。考虑一下:Java 创建了一个 Employee 对象并且构造函数接收值123456789。它如何知道需要将该值分配给哪个变量?它不知道。可以有多个变量属于该对象,因此它不知道123456789真正的含义。

When you don't define a constructor in Java, it automatically creates one for you. But that one does not take any arguments, it's just a default constructor. Your code has several compile errors (for example, the import line for javax is wrong) so I'm guessing you're running a previously compiled version of your code. Remove all .classfiles in your project, fix compile errors and run again. It should give you an error. It'll also make the flow of data a lot easier to understand. The constructor should look something like this:

当您没有在 Java 中定义构造函数时,它会自动为您创建一个。但是那个不带任何参数,它只是一个默认构造函数。您的代码有几个编译错误(例如,javax 的导入行错误),所以我猜您正在运行代码的先前编译版本。删除.class项目中的所有文件,修复编译错误并再次运行。它应该给你一个错误。它还将使数据流更容易理解。构造函数应该是这样的:

public Employee(int empNum) {
    this.empNum = empNum;
}

It now makes a lot more sense that getEmpNum()knows which value to return.

现在getEmpNum()知道要返回哪个值更有意义。

回答by Andrew Fielden

With this class, I don't need to explicitly set a variable because declaring new Employee(123456789) automagically sends that value to the set... method. The return in the Employee method returns the resulting value to the calling method and makes that variable available, in this case to my dialog box output. Do I have a handle on that?

使用这个类,我不需要显式设置变量,因为声明 new Employee(123456789) 会自动将该值发送到 set... 方法。Employee 方法中的 return 将结果值返回给调用方法并使该变量可用,在本例中为我的对话框输出。我有把握吗?

Your understanding is slightly wrong here. The statement

你的理解在这里略有错误。该声明

new Employee(123456789)

is creating a new Employee object by using a constructor method. Constructors usually take parameters which are used to set the internal member variables of the class. So the complete Employee class would be -

正在使用构造函数方法创建一个新的 Employee 对象。构造函数通常采用用于设置类的内部成员变量的参数。所以完整的 Employee 类将是 -

public class Employee
{
  private int empNum;

  public Employee(int employeeNum) {
    empNum = employeeNum;
  }
  public int getEmpNum() {
    return empNum;   
  }
  public void setEmpNum(int Emp) {
    empNum = emp;   
  }
}