我現在正在學習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