我现在正在学习Java,刚刚了解到构造函数是什么。我不明白为什么你需要多个构造函数,如果你需要初始化所有的变量。为什么你需要使用多个构造函数?
回答
一个类可以有多个构造函数,只要它们的签名(参数)不相同。您可以根据需要定义许多构造函数。当一个Java类包含多个构造函数时,我们说构造函数被重载(有多个版本)。这就是构造函数重载意味着什么,一个Java类包含多个构造函数。
话虽如此,它完全依赖于您的实现是否要在您的类中创建多个构造函数,但具有多个构造函数可以在许多情况下缓解您的生活。假设下面的类没有默认的构造函数:
public class Employee {
private int age;
private String name;
Employee(int age, String name){
this.age=age;
this.name=name;
}
}
因此,在创建该类用户的对象将不能够这样做,直到他的年龄和名字参数得心应手制约Java对象的真正功能因为对象的状态应该能够在初始化后随时修改和填充。
每个构造函数都有特定的用途。有时候,我们需要一个以上的构造函数(特别在实体领域的情况下,当使用ORM)
例如:
空构造函数(无参数)进行反思,
构造函数的参数( s)创建新实例(
A a = new A('foo', 'bar');
)。
这些都是超负荷方法。
现实例子:
package sagan.blog;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.hibernate.annotations.Type;
import org.springframework.util.StringUtils;
import sagan.team.MemberProfile;
import javax.persistence.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
/**
* JPA Entity representing an individual blog post.
*/
@Entity
@SuppressWarnings("serial")
public class Post {
private static final SimpleDateFormat SLUG_DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd");
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(cascade = CascadeType.PERSIST, optional = false)
private MemberProfile author;
@Column(nullable = false)
private String title;
@Column(nullable = false)
@Enumerated(EnumType.STRING)
private PostCategory category;
@Column(nullable = false)
@Enumerated(EnumType.STRING)
private PostFormat format;
@Column(nullable = false)
@Type(type = "text")
private String rawContent;
@Column(nullable = false)
@Type(type = "text")
private String renderedContent;
@Column(nullable = false)
@Type(type = "text")
private String renderedSummary;
@Column(nullable = false)
private Date createdAt = new Date();
@Column(nullable = false)
private boolean draft = true;
@Column(nullable = false)
private boolean broadcast = false;
@Column(nullable = true)
private Date publishAt;
@Column(nullable = true)
private String publicSlug;
@ElementCollection
private Set<String> publicSlugAliases = new HashSet<>();
@SuppressWarnings("unused")
private Post() {
}
public Post(String title, String content, PostCategory category, PostFormat format) {
this.title = title;
this.rawContent = content;
this.category = category;
this.format = format;
}
/* For testing only */
public Post(Long id, String title, String content, PostCategory category, PostFormat format) {
this(title, content, category, format);
this.id = id;
}
public Long getId() {
return id;
}
public MemberProfile getAuthor() {
return author;
}
public void setAuthor(MemberProfile author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public PostCategory getCategory() {
return category;
}
public void setCategory(PostCategory category) {
this.category = category;
}
public PostFormat getFormat() {
return format;
}
public void setFormat(PostFormat format) {
this.format = format;
}
public String getRawContent() {
return rawContent;
}
public void setRawContent(String rawContent) {
this.rawContent = rawContent;
}
public String getRenderedContent() {
return renderedContent;
}
public void setRenderedContent(String renderedContent) {
this.renderedContent = renderedContent;
}
public String getRenderedSummary() {
return renderedSummary;
}
public void setRenderedSummary(String renderedSummary) {
this.renderedSummary = renderedSummary;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getPublishAt() {
return publishAt;
}
public void setPublishAt(Date publishAt) {
this.publishAt = publishAt;
publicSlug = publishAt == null ? null : generatePublicSlug();
}
public boolean isDraft() {
return draft;
}
public void setDraft(boolean draft) {
this.draft = draft;
}
public void setBroadcast(boolean isBroadcast) {
broadcast = isBroadcast;
}
public boolean isBroadcast() {
return broadcast;
}
@JsonIgnore
public boolean isScheduled() {
return publishAt == null;
}
@JsonIgnore
public boolean isLiveOn(Date date) {
return !(isDraft() || publishAt.after(date));
}
public String getPublicSlug() {
return publicSlug;
}
public void addPublicSlugAlias(String alias) {
if (alias != null) {
this.publicSlugAliases.add(alias);
}
}
@JsonIgnore
public String getAdminSlug() {
return String.format("%s-%s", getId(), getSlug());
}
private String generatePublicSlug() {
return String.format("%s/%s", SLUG_DATE_FORMAT.format(getPublishAt()), getSlug());
}
@JsonIgnore
private String getSlug() {
if (title == null) {
return "";
}
String cleanedTitle = title.toLowerCase().replace("\n", " ").replaceAll("[^a-z\\d\\s]", " ");
return StringUtils.arrayToDelimitedString(StringUtils.tokenizeToStringArray(cleanedTitle, " "), "-");
}
@Override
public String toString() {
return "Post{" + "id=" + id + ", title='" + title + '\'' + '}';
}
}
类Post
甚至有3建设者命名Post(){...}
来源:https://github.com/spring-io/sagan/blob/master/sagan-common/src/main/java/sagan/blog/Post.java
简单地说,你可以使用多个构造为方便(1例)或者允许完全不同的初始化方法或不同的源类型(第二个示例)
您可能需要多个构造函数来实现你的类简单地允许省略一些已经设置的参数:
//The functionality of the class is not important, just keep in mind parameters influence it.
class AirConditioner{
enum ConditionerMode{
Automatic, //Default
On,
Off
}
public ConditionerMode Mode; //will be on automatic by default.
public int MinTemperature = 18;
public int MaxTemperature = 20;
public AirConditioner(){ //Default constructor to use default settings or initialize manually.
//Nothing here or set Mode to Automatic.
}
//Mode
public AirConditioner(ConditionerMode mode){ //Setup mode, but leave the rest at default
Mode = mode;
}
//setup everything.
public AirConditioner(ConditionerMode mode, int MinTemp, int MaxTemp){
Mode = mode;
MinTemperature = MinTemp;
MaxTemperature = MaxTemp;
}
}
另一个例子是,当不同的构造遵循不同的程序初始化的变量。 例如,您可以拥有一个简单显示文本表的数据表。构造函数可以从数据库或文件中获取数据:
class DataTable{
public DataTable(){} //Again default one, in case you want to initialize manually
public DataTable(SQLConnection con, SQLCommand command){
//Code to connect to database get the data and fill the table
}
public DataTable(File file){
//Code to read data from a file and fill the table
}
}
所以,回想起构造函数的目的是初始化(给它们的值)。 所以觉得这个模型:
public class Car{
private String model; //Objects are null
private int year; // year = 0
Car(String model, int year){
this.model = model;
this.year = year;
}
}
Car对象您的模型和一年创造需求值。如果你可以用每个字段的默认值创建一个虚拟汽车,或者看起来像这样的字符串,那将是非常好的:
"Ford 2016 or "Ford" and "2016"
并创建一个Car对象。
所以,只需创建两个具有不同签名的构造函数即可完成该任务。
另外,假设我们有另一个名为owner的String字段。在创建这个对象时,汽车的拥有者可能并不知道,但是你的程序可能在没有它的情况下运行。所以,我们可以使用上面的相同构造函数,并且Car对象的owner字段将被设置为null。
这是多个构造函数的目的。为了让在说什么对象可以被创建和这变量需要首先进行初始化编程的灵活性。
您也可能会发现这个有用:
- 1. 为什么JAVA需要构造函数?
- 2. Java:为什么你需要构造函数来在父类中使用对象?
- 3. 为什么派生类需要使用基类构造函数
- 4. 为什么使用unordered_map和tuple需要默认构造函数?
- 5. 为什么构造函数中需要apply()函数
- 6. 为什么我们需要一个私有构造函数?
- 7. 为什么BroadcastReceiver需要一个默认构造函数?
- 8. Java实体 - 为什么我需要一个空构造函数?
- 9. 为什么需要这个复制构造函数
- 10. 为什么IMPLEMENT_DYNAMIC需要一个空构造函数?
- 11. 为什么我们需要一个构造函数?
- 12. 为什么我们需要一个私人构造函数?
- 13. 为什么在使用构造函数时需要分配一个空值? Java
- 14. 了解为什么构造函数需要参数?
- 15. 为什么EnumMap构造函数需要类参数?
- 16. 为什么需要迭代器的构造函数需要元素为EmplaceConstructible?
- 17. 你什么时候需要显式调用超类的构造函数?
- 18. 为什么派生的构造函数需要基础析构函数?
- 19. 为什么范围-V3产量需要默认构造函数
- 20. 为什么new()约束需要公共构造函数?
- 21. 为什么复制构造函数需要是const?
- 22. 为什么构造函数需要在课后准确命名?
- 23. 嵌套构造函数。为什么需要?
- 24. 为什么我们需要JPA中的空构造函数。 ??
- 25. 为什么hibernate需要java.lang.Double的默认构造函数?
- 26. 为什么@RequestBody不需要arg构造函数?
- 27. 为什么我们需要OOP中的构造函数?
- 28. 为什么ServletContextAttributeListener需要默认构造函数?
- 29. 为什么类扩展intentservice需要空的构造函数?
- 30. C++构造函数重载 - 为什么说我需要括号?
“需要一个以上的构造函数,如果你需要初始化所有变量”你这个是什么意思?变量可以在一个构造函数中初始化。 –
@KarthikeyanVaithilingam我的意思是我不明白为什么你需要使用多个构造函数,因为你可以初始化一个构造函数中的所有变量,而且我不知道除了初始化变量之外,还有什么可以使用构造函数。对困惑感到抱歉。 – Tren46
它通常主要是为了方便,或者在某些情况下可能有效。查看一些具有多个构造函数的JDK类 - [String](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html)和[ArrayList]( https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html)有一堆,例如 - 它可能会变得更加清晰。 – yshavit