可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
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 Emp
passed 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?
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 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?
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 Employee
class, 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.
I'd love to hear some thoughts about whether or not I'm properly understanding what's happening.
回答1:
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 constructor that takes an integer for an argument and then sets 'empNum' equal to the argued integer value.
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).
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.
回答2:
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 age
and a birthdate
variable. Setting the birthdate
also 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.
In this example, using setters would also allow us to convert the age
variable into a generated property. Since age can be directly determined using the birthdate
, you can create a getter for age
and have it directly calculate and return the age without needing to store it anywhere.
If we use getters and setters to expose these object properties, we are free to switch out the implementations (such as removing the age
variable and calculating it on the fly) without the users of our object needing to worry about it.
回答3:
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.
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.
It really depends on how the Employee class will be used/instantiated.
回答4:
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.
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 123456789
really means.
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 .class
files 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:
public Employee(int empNum) {
this.empNum = empNum;
}
It now makes a lot more sense that getEmpNum()
knows which value to return.
回答5:
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?
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 -
public class Employee
{
private int empNum;
public Employee(int employeeNum) {
empNum = employeeNum;
}
public int getEmpNum() {
return empNum;
}
public void setEmpNum(int Emp) {
empNum = emp;
}
}