到目前为止,我已经看到了两种在 Java 中设置变量值的方法。有时使用带参数的构造函数,其他 setter 方法用于设置每个变量的值。
我知道一旦使用“new”关键字实例化了一个类,构造函数就会在类中初始化一个实例变量。
但是我们什么时候使用构造函数,什么时候使用设置器呢?
原文由 ssayyed 发布,翻译遵循 CC BY-SA 4.0 许可协议
到目前为止,我已经看到了两种在 Java 中设置变量值的方法。有时使用带参数的构造函数,其他 setter 方法用于设置每个变量的值。
我知道一旦使用“new”关键字实例化了一个类,构造函数就会在类中初始化一个实例变量。
但是我们什么时候使用构造函数,什么时候使用设置器呢?
原文由 ssayyed 发布,翻译遵循 CC BY-SA 4.0 许可协议
我认为您问了一个很好的问题:-但是我们什么时候使用构造函数,什么时候使用设置器?
首先,让我们从一些概念开始。我希望这个解释能帮助每个想知道何时使用构造函数或 setters() 和 getters() 方法(访问器和修改器)的人。 构造函数 类似于 方法,但是在 java 中 构造函数 和 方法 之间几乎没有区别:
构造函数 用于初始化对象的状态。 方法 用于公开对象的行为。
构造函数 不能有返回类型。 方法 必须有返回类型。
构造函数 被隐式调用。显式调用 _方法_。
Getters() 或访问器是提供对对象实例变量的访问的方法。 Setters() 或更改器是为调用者提供更新特定实例变量值的机会的方法。
清楚这一点后,让我们从面向对象编程 (OOP) 的角度来考虑,以满足 OOP 原则的要求( 面向对象编程 (OOP) 是基于 四个主要原则 构建的: _封装_、 _数据抽象_、 多态性 和 _继承_。)、 Getter () 和 Setter() 方法是实现这一点的关键。
这是一个向您展示我的意思的公式:
私有字段 + 公共访问器 == 封装;
正如您基于此公式所见,当我们设置私有字段并使用公共访问器时,我们正在执行 4 个 OOP 原则之一的封装。
在这里,我将为您提供两个类,我在上面添加了注释,试图让我的代码自我解释。将这些类作为方法的实验室 Customer
和 TestCustomer
[带有 main()
方法的那个] 类,你可以自己复制代码并运行。请注意,我使用了两个构造函数来解释一个具有多个构造函数并具有公共 setters()
和 getters()
方法以访问私有实例变量的类:
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
}
}
这是测试类,具有 main()
方法并在实例化预览类的对象后调用实例方法的类:
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());
}
}
结果:
客户姓名:Juan Melendez,SSN#:123457789
客户姓名:Mary Lee,SSN#:125997536
客户姓名:John Doe,SSN#:124963574
原文由 S. Mayol 发布,翻译遵循 CC BY-SA 4.0 许可协议
15 回答8.3k 阅读
8 回答6.2k 阅读
1 回答4k 阅读✓ 已解决
3 回答6k 阅读
3 回答2.2k 阅读✓ 已解决
2 回答3.1k 阅读
2 回答3.8k 阅读
当您想要创建对象的新实例时,您应该使用构造函数方法,并且已经填充了值(一个准备好使用的对象,并填充了值)。这样您就不需要为对象中的每个字段显式调用 setter 方法来填充它们。
当您想要在创建对象后更改字段的值时,您可以使用 setter 方法设置值。
例如:-
正如 Axel 提到的, _如果你想创建不可变对象,你不能使用 setter 方法。我不会说所有东西都必须在构造函数中初始化,因为存在不同的方法,比如惰性求值,它甚至可以用于不可变对象_。