Tren46
Tren46

Reputation: 193

Why would you need to use more than one constructor?

I am learning Java as of right now and have just been learned what constructors are. I do not understand why you would need more than one constructor if you need to initialize all variables.

Upvotes: 8

Views: 45966

Answers (4)

Dun
Dun

Reputation: 11

So, recall that the purpose of the constructor is to initialize (give them values). So think of this model:

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

The Car object you create needs values for the model and the year. It would be great if you could just create a dummy car with just default values for each field, or take a string that looks like this:

"Ford 2016 or "Ford" and "2016" and create a Car object.

So, just create two more constructors with different signatures that accomplish that task.

Also, imagine we have another String field called owner. The owner of a car may not be know at the creation of this object, but your program may be able to function without it. So, we can use the same constructor above and the Car object's owner field will be set to null.

That's the purpose for multiple constructors. To give the programmer flexibility on saying what an object can be created from and which variables need to be initialized in the first place.

You may also find this useful:

enter image description here

Upvotes: 0

Zero
Zero

Reputation: 1646

To put it simply, you use multiple constructors for convenience (1st example) or to allow completely different initialization methods or different source types (2nd example.

You might need multiple constructors to implement your class to simply allow omitting some of the parameters that are already setup:

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

Another example is when different constructors follow different procedures to initialize the variables. For instance you could have a data table that simply displays a table of text. The constructor could get the data from either database OR a file:

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

Upvotes: 9

Harish Vashist
Harish Vashist

Reputation: 86

A class can have multiple constructors, as long as their signature (the parameters they take) are not the same. You can define as many constructors as you need. When a Java class contains multiple constructors, we say that the constructor is overloaded (comes in multiple versions). This is what constructor overloading means, that a Java class contains multiple constructors.

Having said that, it is completely dependent upon your implementation whether or not you want to create more than one constructor in your class but having more than one constructor can ease your life in many instances. Suppose below class doesn't have a default constructor:

public class Employee {

    private int age;
    private String name;

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

So, while creating object of this class user would not be able to do so until he has age and name parameters handy which restricts the true functionality of Java objects as Objects' state should be able to be modified and populated at any time once initialized.

Upvotes: 4

Vy Do
Vy Do

Reputation: 52516

Per constructor has specific purpose. Sometimes we need more than one constructor (special in Entity domain case, when use ORM)

For example:

  • Empty constructor (no arguments) for reflection,

  • Constructor has argument(s) for create new instance (A a = new A('foo', 'bar');).

These're overload method(s).

Reality example:

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 + '\'' + '}';
    }
}

Class Post even has 3 constructors named Post(){...}

Source: https://github.com/spring-io/sagan/blob/master/sagan-common/src/main/java/sagan/blog/Post.java

Upvotes: 0

Related Questions