为什么需要使用多个构造函数?

时间:2016-05-30 04:14:46

标签: java constructor

我正在学习Java,并且刚刚学习了构造函数。如果你需要初始化所有变量,我不明白为什么你需要多个构造函数。

4 个答案:

答案 0 :(得分:4)

简单地说,为方便起见,使用多个构造函数(第1个例子)或允许完全不同的初始化方法或不同的源类型(第2个例子。

您可能需要多个构造函数来实现您的类,只需省略一些已经设置的参数:

function forceNumber(element) {
  element
    .data("oldValue", '')
    .bind("paste", function(e) {
      var validNumber = /^[-]?\d+(\.\d{1,2})?$/;
      element.data('oldValue', element.val())
      setTimeout(function() {
        if (!validNumber.test(element.val()))
          element.val(element.data('oldValue'));
      }, 0);
    });
  element
    .keypress(function(event) {
      var text = $(this).val();
      if ((event.which != 46 || text.indexOf('.') != -1) && //if the keypress is not a . or there is already a decimal point
        ((event.which < 48 || event.which > 57) && //and you try to enter something that isn't a number
          (event.which != 45 || (element[0].selectionStart != 0 || text.indexOf('-') != -1)) && //and the keypress is not a -, or the cursor is not at the beginning, or there is already a -
          (event.which != 0 && event.which != 8))) { //and the keypress is not a backspace or arrow key (in FF)
        event.preventDefault(); //cancel the keypress
      }

      if ((text.indexOf('.') != -1) && (text.substring(text.indexOf('.')).length > 2) && //if there is a decimal point, and there are more than two digits after the decimal point
        ((element[0].selectionStart - element[0].selectionEnd) == 0) && //and no part of the input is selected
        (element[0].selectionStart >= element.val().length - 2) && //and the cursor is to the right of the decimal point
        (event.which != 45 || (element[0].selectionStart != 0 || text.indexOf('-') != -1)) && //and the keypress is not a -, or the cursor is not at the beginning, or there is already a -
        (event.which != 0 && event.which != 8)) { //and the keypress is not a backspace or arrow key (in FF)
        event.preventDefault(); //cancel the keypress
      }
    });
}

forceNumber($("#myInput"));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="myInput" />

另一个例子是不同的构造函数遵循不同的过程来初始化变量。 例如,您可以拥有一个只显示文本表的数据表。构造函数可以从任一数据库或文件中获取数据:

//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;
   }
}

答案 1 :(得分:1)

一个类可以有多个构造函数,只要它们的签名(它们采用的参数)不一样。您可以根据需要定义任意数量的构造函数。当Java类包含多个构造函数时,我们说构造函数被重载(有多个版本)。这就是构造函数重载意味着Java类包含多个构造函数。

话虽如此,它完全取决于您的实现是否要在您的类中创建多个构造函数但具有多个构造函数可以在许多情况下缓解您的生活。假设下面的类没有默认构造函数:

public class Employee {

    private int age;
    private String name;

    Employee(int age, String name){
        this.age=age;
        this.name=name;     
    }
}

因此,在创建此类的对象时,用户将无法这样做,直到他有年龄和名称参数方便,这限制了Java对象的真正功能作为对象&#39;初始化后,任何时候都应该能够修改和填充状态。

答案 2 :(得分:0)

每个构造函数都有特定的用途。有时我们需要多个构造函数(特殊于Entity域情况,使用ORM时)

例如:

  • 反射的空构造函数(无参数),

  • 构造函数具有创建新实例(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

答案 3 :(得分:0)

所以,回想一下构造函数的目的是初始化(给它们赋值)。 所以想想这个模型:

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对象的所有者字段设置为null。

这是多个构造函数的目的。为了让程序员灵活地说 可以创建一个对象, 哪些 变量需要初始化第一名。

您可能还会发现这很有用:

enter image description here