mk8139
mk8139

Reputation: 57

How do you know what type of constructor to use?

I know this is probably a very stupid question but I've looked at a lot of different sources and I can't seem to understand the difference between the no-arg constructor and the constructors with arguments. I'm under the impression that the no-arg constructor accepts as many arguments as you want, and the constructors with, say, 2 arguments, only accepts 2.

 import java.io.*;      //the File class
 import java.util.*;    //the Scanner class

 public class Distance implements Comparable<Distance>
 {
     private int myFeet, myInches;

     public Distance()
     {
         myFeet = myInches = 0;
     }

     public Distance(int f, int i)
     {
         myFeet = f;
         myInches = i;
     }

     public Distance(Distance arg)
     {
         myFeet = arg.getFeet();
         myInches = arg.getInches();
     }
}

I just don't understand why it's necessary to have both Distance(int f, int i) and Distance(Distance arg) and how you know which constructors to use. Also, what is Distance arg? Is "arg" just a placeholder variable or is it an actual Java keyword? It'd be great if I could get an explanation about constructors!

Upvotes: 0

Views: 355

Answers (4)

Kedar Mhaswade
Kedar Mhaswade

Reputation: 4695

Short answers:

I'm under the impression that the no-arg constructor accepts as many arguments as you want, and the constructors with, say, 2 arguments, only accepts 2.

A no-arg or parameterless constructor accepts no arguments. This is for the purpose of creating a default instance of a given class. In fact, if you did not provide any constructor, Java compiler provides a default no-arg constructor for your class. If you declare a constructor with n arguments (e.g. public Person(String name, int age), then constructing an instance of that class by calling that constructor requires you to provide the correct number, type and order of those arguments (e.g. Person p = new Person("Larry", 32)).

Perhaps you are confusing this type of constructor with a vararg or variable arity method that accepts one or more arguments of a given type (there are some gory details that you should read up). Since a constructor of a class is similar to any other instance method (there are differences), you could have variable arity constructors, but they are rarely used:

class Chameleon {
    private final String color;
    private final String location;
    private final int lifeSpanYears;
    /**
     * Constructs a default Chameleon that has GREEN color, is from Africa and
     * has 5 years of life span.
    */
    public Chameleon() {
        this.color = "GREEN";
        this.location = "Africa";
        this.lifeSpanYears = 5;
    }
    /**
     * Constructs a specific instance of Chameleon with given color, location
     * and life span.
     */
    public Chameleon(String color, String location, int lifeSpanYears) {
        //validate arguments
        this.color = color;
        this.location = location;
        this.lifeSpanYears = lifeSpanYears;
    }
    /* Constructs a Chameleon from given one or more string params.
       If given, first argument is the color and if given, the second
       argument is the location. Life span of the instance will be 5 years.
       <b> Note: this is for illustration purposes only. </b>
    */
    public Chameleon(String... props) {
        if (props.length == 0) {
            this.color = "GREEN";
            this.location = "Africa";
        } else if (props.length == 1) {
            this.color = props[0];
            this.location = "Africa";
        } else {
            this.color = props[0];
            this.location = props[1];
        }
        this.lifeSpanYears = 5;
    }
    public Chameleon(Chameleon mold) {
        this.color = mold.color;
        this.location = mold.location;
        this.lifeSpanYears = mold.lifeSpanYears;
    }
    public static void main(String[] args) {
        Chameleon c = new Chameleon(); // no-arg constructor is called
        System.out.println(c.color); // => GREEN
        System.out.println(c.location); // => Africa
        System.out.println(c.lifeSpanYears); // 5

        Chameleon c2 = new Chameleon("BLACK", "Asia", 4); // specific constructor is called, right number, type and order of arguments is provided
        System.out.println(c2.color); // => BLACK
        System.out.println(c2.location); // => Asia
        System.out.println(c2.lifeSpanYears); // 4

        Chameleon c3 = new Chameleon("BROWN", "California"); // this time it should be the vararg constructor!
        System.out.println(c3.color); // => BROWN
        System.out.println(c3.location); // => California
        System.out.println(c3.lifeSpanYears); // 5 again

        Chameleon c4 = new Chameleon("BROWN"); // this time it should be the vararg constructor again!
        System.out.println(c4.color); // => BROWN
        System.out.println(c4.location); // => Africa
        System.out.println(c4.lifeSpanYears); // 5 again

        Chameleon c5 = new Chameleon(c2); // this time the _copy_ constructor is called. c5 is a copy of c2.
        // although c5 is a copy of c2, it is a distinct entity; think of c5 as
        // an identical twin of c2.
        System.out.println(c5.color); // => BLACK
        System.out.println(c5.location); // => Asia
        System.out.println(c5.lifeSpanYears); // 4
    }
}

I just don't understand why it's necessary to have both Distance(int f, int i) and Distance(Distance arg)

Well, it is not necessary per se. It's a convenience. The underlying mechanism that enables this is called method overloading which means you could declare two constructors (or methods) with the same name (class name in this case) in a class. Every constructor can construct an instance of a class in a way it chooses to. Ideally, all the constructors should construct properly initialized instances. If you followed some basic object oriented programming good practices, you should not go wrong here.

In this particular case, you are providing two constructors: the first that takes both feet and inches and the other that takes another instance of the same class. The second constructor embodies what is knows as a copy constructor which should create a copy of the passed argument. Thus, if you have an already available instance d of the Distance class, you can create a copy of that using: // get d from somewhere Distance dCopy = new Distance(d); See the copy constructor (and its use) provided in my example code above.

and how you know which constructors to use

Here you will need to read the documentation or source of the class that you intend to use. Well-written classes like the JDK provide good documentation for you to look at.

Also, what is Distance arg?

It is an instance of the class Distance that is used as a constructor argument. Again, see the main method of the Chameleon example.

Is "arg" just a placeholder variable or is it an actual Java keyword?

Yes, the former. It's more commonly known as an argument or a formal parameter.

Upvotes: 2

Pritam Pallab
Pritam Pallab

Reputation: 68

  1. If no external constructor is written then it will take its default constructor ( Which is handled by java internally ).
  2. If for a class A , a constructor public A() is present then it will consider this one as a constructor.

Now if you have a constructor like,

public A()
{
    <something>
}

Then while creation of object you have to write just,

A objectA = new A();

If you have a constructor like,

public A(int x)
{
    <something>
}

then while declaring you have to write,

A objectA = new A(<any integer>);

Here you can't write,

A objectA = new A();

So when you are declaring constructor then only those will be considered. Now in your code,

public Distance()
 {
        myFeet = myInches = 0;
 }
 public Distance(int f, int i)
 {
        myFeet = f;
        myInches = i;
 }
public Distance(Distance arg)
{
        myFeet = arg.getFeet();
        myInches = arg.getInches();
 }

You can create the object of Distance class in three manners,

Distance distance = new Distance();

Distance distance = new Distance(1,2);

Distance distance2 = new Distance();
Distance distance = new Distance(distance2);

So in all the cases the object is created and the values are initialized. But it is written in multiple way to approve multiple type or mannered coding and to give the code more options to create the object. Lastly arg is just a variable name.

Upvotes: 1

Bill the Lizard
Bill the Lizard

Reputation: 405785

A no-arg constructor takes 0 arguments (no arguments). It just runs the code inside the constructor, and you'll often see it used to initialize values to some pre-determined defaults (like yours that just sets feet and inches both to 0). In contrast, a constructor that takes in arguments can have its values set to different values at run-time.

This constructor

public Distance(Distance arg)

is called a copy constructor. It takes in an argument of the same class and just copies its attributes into the current object under construction.

Which constructor you use is entirely based on what you need. Some classes won't have all types of constructors defined, so you're limited. Others will have several constructors defined, so you can use whichever one the situation calls for.

Upvotes: 2

Pritam Banerjee
Pritam Banerjee

Reputation: 18923

Constructors are used to instantiate a Class.

There can be default constructors which does not initialize any of the properties in the class.

In your code the default constructor is :

public Distance()
{
 myFeet = myInches = 0;
}

A class can be instantiated in many ways, and for that constructors are needed. There can arguments in constructors. These arguments automatically set the properties of the class inside the constructors. So we don't need to set the properties individually.

For eg in your code:

 public Distance(int f, int i)
  { 
    myFeet = f;
    myInches = i;
  }
 public Distance(Distance arg)
 {
  myFeet = arg.getFeet();
  myInches = arg.getInches();
 }

In the first constructor the properties are set individually in the constructor.

In the second case it is set from another Distance Object.

Args is not a keyword, it is the name of the object of type Distance.

Upvotes: 1

Related Questions