Advertisement

When to use a constructor

Started by June 12, 2017 12:27 PM
7 comments, last by dmatter 7 years, 5 months ago

Hi guys,

Hope everyone's having a productive day!

So In my coding I'm creating an object of the class say "decor", I'm writing this inside of the class say "Furniture". So if I want to create that object of the class Decor then Decor will need the constructor, can I create the constructor for decor inside of the class Furniture or must it be inside the class that the constructor is for ? Does this depend on the access modifier for the class Furniture ?

Advertisement

Im not doing anything regarding inner classes.

See here if you wish:

https://www.gamedev.net/topic/689300-updating-reading-from-an-array/

The linked topic doesn't really explain the problem you have.

A constructor for a class performs any extra setup that the class needs when creating a new instance of itself. If Furniture has a member called 'decor', it could initialise that inside the Furniture constructor. The decor object doesn't need a constructor, but if it is of some other class, then that class may need a constructor.

So In my coding I'm creating an object of the class say "decor", I'm writing this inside of the class say "Furniture". So if I want to create that object of the class Decor then Decor will need the constructor, can I create the constructor for decor inside of the class Furniture or must it be inside the class that the constructor is for ?

To start with the last part, a constructor for a class is always written as part of the class, regardless of where you use objects of it.

There may be some confusion what "constructor" is. For me, it is a method like "public Furniture()" below:


public class Furniture {
    public Furniture() { ... }
    ....
}

When you instantiate a class (with "new Furniture()"), you go from nothing to an object of type Furniture. As part of that creation process, the constructor is called, and its purpose is to initialize the new object, ie give all its data members a value (it has none, so that's quite simple, but see below). After the constructor finishes, you have an object, and you get a reference to the new object from the "new" statement. Usually, the first thing you do is to store that reference, as in "Furniture furniture = new Furniture();"

If a class has variables of its own, like your decor class, there are two ways to initialize the variables.


public class Decor {
    private Furniture table;
    private Furniture chair = new Furniture();

    public Decor() {
        table = new Furniture();
        ....
    }
    ...
}

The Decor class has its own "public Decor" constructor. The statement in it ("table = new Furniture();") constructs a new furniture, and assigns it to the object variable "table". The "private Furniture chair = new Furniture();" here does functionally the same as what "table = new Furniture();" did, it constructs a new furniture object, and assigns it to the "chair" variable.

So this is how it works, each class has its own constructor that initializes all variables of that class. If the type of the variables is again a class, those constructors are executed first to construct the smaller objects first.

The advantage of having a constructor in its own class is that the inner objects don't need to know anything about where they are used. You could use your Furniture class also for furniture at a ship, for example. The ship then needs to know there exists a Furniture class, but the Furniture class doesn't need to know about ships at all.

Does this depend on the access modifier for the class Furniture ?

It doesn't, the access modifier only specifies who can call the method. For example, you could make constructor less available than some other method, like "public int compute(int x)". An external user then cannot create an object of that class by itself (only objects with sufficient access rights to its constructors can call the constructor, and in doing so, create the object), but the external user could call the "compute" method, if it gets a reference to an object of that type. In other words, access modifiers only ensure that "wrong" objects don't have access to methods they are not supposed to use.

This is quite full of holes though, in practice. The various classifiers are not fine-grained enough to catch all bad uses. It does however give you some crude control, anything beyond that you will have to handle manually, mostly by documenting who is supposed to use a method.

Advertisement

Thanks for clearing this up, so with what I've gathered here I'll write an example, from there I've got a question regarding constructor parameters but let me write it first.


package Sims;
public class House
{
   public House() //House class Constructor (no parameters)
   {
   }
   
    public static void main(String[] args)
    {
          House Toms_House = new House();
    }
}

If my above code is correct, I've got one class "House", with a constructor for the class "House" without parameters, I then have a line of code in the main class which creates a new object of the class House where the object name is "Toms_House".

Also, this new object of House will have no variables, but if I add variables to class House and assign values to those variables, they will be copied over to the new object of House called "Toms_House" ?

The reason I'm asking if the new keyword makes an exact copy of the 'schematic' class House, is because I don't understand what the parameters are for within the constructor.

I think I need to start off with understanding what parameters are used for, before asking why they are used in the constructor. Some potatoes are complaining about me creating multiple posts even though they are different, so I'll rather ask here for now.

I'm going to read up a bit about parameters/arguments, then I'll update this post.

The reason I'm asking if the new keyword makes an exact copy of the 'schematic' class House, is because I don't understand what the parameters are for within the constructor.

Not quite, some languages do work that way but not Java.

A class is like a "schematic" or "blueprint" for objects. You construct those objects using the 'new' keyword.

When an object is constructed (using 'new') the constructor is executed and the idea is to do any setup of the object that you need to.

Constructor parameters are available so that you can provide some input to that setup process.

As an example, take your existing House class. We know that in the real world every house has a street address but we know that each house object should have its own address. So we can provide this through the constructor:


public class House
{
    public String address;

    // a constructor with a parameter
    public House(String addressParam) {
        // the constructor's job is to do setup on a per-object basis
        address = addressParam;
    }
   
    public static void main(String[] args)
    {
          House Toms_House = new House("21 Java Street");
          System.out.println(Toms_House.address); // prints: 21 Java Street
    }
}

Note that a better way of writing that constructor would be like this:


public House(String address) {
    this.address = address;
}

(Note the "this." syntax to distinguish it as being the address member variable as opposed to the address parameter variable).

Isn't that the same as this ..


public class House
{
public String address;

// a constructor with a parameter
public House() {
// the constructor's job is to do setup on a per-object basis

}

public static void main(String[] args)
{
House Toms_House = new House();
Toms_House.address = "21 Java Street";
System.out.println(Toms_House.address); // prints: 21 Java Street
}
}

Isn't that the same as this ..

Pretty much!

The key difference is that with the constructor approach it means the object was responsible for setting itself up (an easy to use class) and the code for that setup is physically positioned within the class (easy to find and maintain that code!)

Whereas in your example it is up to the user of the House class to do the setup and they need to run/write that code in every place where they construct House objects. This makes the class hard to use and harder to find & maintain that setup code.

Okay, in this example we are just assigning to a variable. But imagine if that setup logic was drastically more complicated. You (as the class's author) would not want the users of this class to have to write that same code every time. Better that you do it once, here and get it right. Then users don't need to worry/care about 'how' to setup these objects, they just need to pass the relevant information in as parameters and trust that whatever setup needs to be done will take place correctly.

This topic is closed to new replies.

Advertisement